<div class="show-content-free"> <h2>一. 場景</h2> <blockquote> <p>現有倆個體積較大的單表sql文件,一個爲8G,一個爲4G,要在一天內完整導入到阿里雲的mysql中,須要同時蠻子時間和空間這倆種要求。</p> </blockquote> <h2>二. 思路</h2> <blockquote> <p>搜索了網上一堆的方案,總結了以下幾個:<br> 方案一:利用navicat遠程導入<br> 方案二:在阿里雲ECS安裝一個mysql-client,用source方案導入<br> 方案三:購買阿里雲DBMS高級版服務,能夠導入1G之內ZIP壓縮包</p> </blockquote> <h2>三. 嘗試</h2> <p>折騰了許久的嘗試,終於總結了一下的經驗:</p> <h3>3.1 嘗試navicat遠程導入</h3> <blockquote> <p>操做簡單,可是缺點很明顯:導入效率低,嚴重佔用本地的IO,影響機器的正常工做,因此立馬放棄。</p> </blockquote> <h3>3.2 嘗試source方案</h3> <h4>3.2.1 實現步驟</h4> <blockquote> <p><strong>STEP1</strong> 在測試環境的ECS上安裝一個mysql-client<br> <strong>STEP2</strong> 修改mysql中的<strong>max_allowed_packet</strong>參數爲<strong>10G</strong>大小,<strong>net_buffer_length</strong>參數也根據需求適度調大。<br> <strong>STEP3</strong> 由於是倆個表,寫倆個腳本太麻煩了,能夠利用一個sql腳本聚合實現,因此all.sql 的內容能夠以下</p> </blockquote> <pre class="hljs bash"><code class="bash hljs"><span class="hljs-built_in"><span class="hljs-built_in">source</span></span> /mydata/sql/a.sql; <span class="hljs-built_in"><span class="hljs-built_in">source</span></span> /mydata/sql/b.sql; </code></pre> <blockquote> <p><strong>STEP4</strong> 爲避免ssh鏈接掉線而致使執行關閉,須要寫一個shell腳本,經過nohup後臺執行。<br> myshell.sh腳本以下</p> </blockquote> <pre class="hljs javascript"><code class="javascript hljs">mysql -h host -uxxx -pxxx --database=user_database<<span class="hljs-regexp"><span class="hljs-regexp">/mydata/</span></span>sql/all.sql </code></pre> <blockquote> <p><strong>STEP5</strong> 後臺執行指令</p> </blockquote> <pre class="hljs undefined"><code class="hljs nginx"><span class="hljs-attribute">nohup</span> ./myshell.sh & </code></pre> <h4>3.2.2 結果</h4> <blockquote> <p>測試速度相對快多了,可是因爲次日就須要,因此倆個表接近4000w行的數據絕對不能完成任務,因此方案取消。可是不是否認該方案,其餘場景確定知足。</p> </blockquote> <h3>3.3 嘗試DMBS</h3> <p>因爲咱們數據庫是阿里雲的RDS,因此咱們購買了對應的DBMS服務升級版,能夠支持文件上傳導入(包含1G內的ZIP)</p> <br> <div class="image-package"> <div class="image-container" style="max-width: 653px; max-height: 412px; background-color: transparent;">javascript
<div class="image-view" data-width="653" data-height="412"><img data-original-src="//upload-images.jianshu.io/upload_images/3362699-5b22590a7e292cc9.png" data-original-width="653" data-original-height="412" data-original-format="image/png" data-original-filesize="27334" class="" style="cursor: zoom-in;" src="https://img2018.cnblogs.com/blog/1112483/201908/1112483-20190822094334846-1850490909.png"></div> </div> <div class="image-caption">DBMS功能</div> </div> <h4>3.3.1 壓縮文件</h4> <p>壓縮單表SQL文件爲單獨zip文件,壓縮下來一個爲0.9G,一個爲1.2G</p> <h4>3.3.2 拆分文件</h4> <p>第一個sql文件上傳後執行很順利,可是第二個1.2G的zip包須要進行拆分</p> <h4>3.3.3 拆分方案</h4> <p><strong>1.拆分zip壓縮包</strong><br> </p><div class="image-package"> <div class="image-container" style="max-width: 460px; max-height: 440px; background-color: transparent;">css
<div class="image-view" data-width="460" data-height="440"><img data-original-src="//upload-images.jianshu.io/upload_images/3362699-7dcccb9fcf2d1029.png" data-original-width="460" data-original-height="440" data-original-format="image/png" data-original-filesize="31932" class="" style="cursor: zoom-in;" src="https://img2018.cnblogs.com/blog/1112483/201908/1112483-20190822094359883-1398213167.png"></div> </div> <div class="image-caption">壓縮包拆分</div> </div><br> 拆分出來的文件,手動改後綴後不知足DBMS的文件規範,失敗~<br> <strong>2.高比例壓縮文件</strong><br> 利用7z高比例壓縮sql爲7z後綴,壓縮後體積明顯小了,只有0.7G的體積,而後經過更改後綴爲zip來上傳。結果阿里雲解析不出這樣的格式,失敗~<br> <strong>3.使用linux split 命令</strong><p></p> <pre class="hljs css"><code class="css hljs"><span class="hljs-selector-tag"><span class="hljs-selector-tag">split</span></span> <span class="hljs-selector-attr"><span class="hljs-selector-attr">[--help]</span></span><span class="hljs-selector-attr"><span class="hljs-selector-attr">[--version]</span></span><span class="hljs-selector-attr"><span class="hljs-selector-attr">[-<行數>]</span></span><span class="hljs-selector-attr"><span class="hljs-selector-attr">[-b <字節>]</span></span><span class="hljs-selector-attr"><span class="hljs-selector-attr">[-C <字節>]</span></span><span class="hljs-selector-attr"><span class="hljs-selector-attr">[-l <行數>]</span></span><span class="hljs-selector-attr"><span class="hljs-selector-attr">[要切割的文件]</span></span><span class="hljs-selector-attr"><span class="hljs-selector-attr">[輸出文件名]</span></span> </code></pre> <blockquote> <p>補充說明:<br> split可將文件切成較小的文件,預設每1000行會切成一個小文件。<br> -<行數>或-l<行數> 指定每多少行就要切成一個小文件。<br> -b<字節> 指定每多少字就要切成一個小文件。支持單位:m,k<br> -C<字節> 與-b參數相似,但切割時儘可能維持每行的完整性。</p> </blockquote> <p>雖然linux能夠根據行拆分文件(這也是阿里雲工單提供的解決方案),可是這個操做上傳上去拆分,在下載下來上傳到DBMS,文件體積這麼大,來來回回一天過去了,因此放棄~<br> <strong>4.拆分單表sql文件爲多份</strong><br> 網上有個SQLDumpSplitter的工具能夠拆分表爲多份,可是搜索記錄中和文章中都是推薦SQLDumpSplitter2的版本,版本太老了,體積較大的sql徹底不支持,失敗~<br> 可是!我在SQLDumpSplitter2裏面看到了軟件的官網,發現官網有SQLDumpSplitter3版本,不抱但願的嘗試了一下,竟然支持大致積文件。成功了!!!<br> 附帶下載連接:<a href="https://links.jianshu.com/go?to=https%3A%2F%2Fphiliplb.de%2Fsqldumpsplitter3%2F" target="_blank">https://philiplb.de/sqldumpsplitter3/</a> 太值得推廣了。<br> </p><div class="image-package"> <div class="image-container" style="max-width: 455px; max-height: 274px; background-color: transparent;">java
<div class="image-view" data-width="455" data-height="274"><img data-original-src="//upload-images.jianshu.io/upload_images/3362699-f7d2f4e1b5aa07e0.png" data-original-width="455" data-original-height="274" data-original-format="image/png" data-original-filesize="24174" class="" style="cursor: zoom-in;" src="https://img2018.cnblogs.com/blog/1112483/201908/1112483-20190822094425842-452379798.png"></div> </div> <div class="image-caption">SQLDumpSplitter3</div> </div><br> <div class="image-package"> <div class="image-container" style="max-width: 700px; max-height: 480px; background-color: transparent;">mysql
<div class="image-view" data-width="1176" data-height="480"><img data-original-src="//upload-images.jianshu.io/upload_images/3362699-00e675ab7893cae9.png" data-original-width="1176" data-original-height="480" data-original-format="image/png" data-original-filesize="66057" class="" style="cursor: zoom-in;" src="https://img2018.cnblogs.com/blog/1112483/201908/1112483-20190822094448944-973299596.png"></div> </div> <div class="image-caption">拆分結果</div> </div><br> 剩下就是按序上傳對應文件便可完成,不得不得誇阿里雲這方面作得真的好!<br> <div class="image-package"> <div class="image-container" style="max-width: 700px; max-height: 341px; background-color: transparent;">linux
<div class="image-view" data-width="1567" data-height="341"><img data-original-src="//upload-images.jianshu.io/upload_images/3362699-88b55f7b7382681c.png" data-original-width="1567" data-original-height="341" data-original-format="image/png" data-original-filesize="50643" class="" style="cursor: zoom-in;" src="https://img2018.cnblogs.com/blog/1112483/201908/1112483-20190822094513410-1506194439.png"></div> </div> <div class="image-caption">多任務執行</div> </div><br> 執行效率上面來講,也是可圈可點的:<br> <div class="image-package"> <div class="image-container" style="max-width: 694px; max-height: 125px; background-color: transparent;">nginx
<div class="image-view" data-width="694" data-height="125"><img data-original-src="//upload-images.jianshu.io/upload_images/3362699-f96b475f702914ce.png" data-original-width="694" data-original-height="125" data-original-format="image/png" data-original-filesize="16884" class="" style="cursor: zoom-in;" src="https://img2018.cnblogs.com/blog/1112483/201908/1112483-20190822094536752-1873678646.png"></div> </div> <div class="image-caption">切片入庫的效率</div> </div><p></p> <h2>四. 總結</h2> <blockquote> <p><strong>今天針對這個需求,我首先查詢了網上的大致方案,而後挑選了幾個可執行的方案進行測試。排除了多個方案的狀況下,採用了第三方的解決方案來完成這個問題。在阿里雲DBMS的支持下,咱們又嘗試了多種文件的切割方案,最後經過SQLDumpSplitter3+DBMS來實現了,而且效率可觀。過程當中也發現,經常使用的client-source方案能夠知足自建mysql+效率要求不是極致的場景。<br> 綜上,對於大型sql,最好的方案也是先切割(確保順序性),而後利用一些更高效率的軟件執行來實現最終結果,也須要根據時間空間場景靈活選用方案。</strong></p> </blockquote> 原文地址:https://www.jianshu.com/p/968fa5963d07 </div>sql