一. 場(chǎng)景
現(xiàn)有倆個(gè)體積較大的單表sql文件啄清,一個(gè)為8G,一個(gè)為4G,要在一天內(nèi)完整導(dǎo)入到阿里云的mysql中计露,需要同時(shí)蠻子時(shí)間和空間這倆種要求该押。
二. 思路
搜索了網(wǎng)上一堆的方案,總結(jié)了如下幾個(gè):
方案一:利用navicat遠(yuǎn)程導(dǎo)入
方案二:在阿里云ECS安裝一個(gè)mysql-client,用source方案導(dǎo)入
方案三:購(gòu)買阿里云DBMS高級(jí)版服務(wù),可以導(dǎo)入1G以內(nèi)ZIP壓縮包
三. 嘗試
折騰了許久的嘗試言蛇,終于總結(jié)了一下的經(jīng)驗(yàn):
3.1 嘗試navicat遠(yuǎn)程導(dǎo)入
操作簡(jiǎn)單,但是缺點(diǎn)很明顯:導(dǎo)入效率低严沥,嚴(yán)重占用本地的IO猜极,影響機(jī)器的正常工作,所以立馬放棄消玄。
3.2 嘗試source方案
3.2.1 實(shí)現(xiàn)步驟
STEP1 在測(cè)試環(huán)境的ECS上安裝一個(gè)mysql-client
STEP2 修改mysql中的max_allowed_packet參數(shù)為10G大小跟伏,net_buffer_length參數(shù)也根據(jù)需求適度調(diào)大。
STEP3 因?yàn)槭莻z個(gè)表翩瓜,寫(xiě)倆個(gè)腳本太麻煩了受扳,可以利用一個(gè)sql腳本聚合實(shí)現(xiàn),所以all.sql 的內(nèi)容可以如下
source /mydata/sql/a.sql;
source /mydata/sql/b.sql;
STEP4 為避免ssh連接掉線而導(dǎo)致執(zhí)行關(guān)閉兔跌,需要寫(xiě)一個(gè)shell腳本勘高,通過(guò)nohup后臺(tái)執(zhí)行。
myshell.sh腳本如下
mysql -h host -uxxx -pxxx --database=user_database</mydata/sql/all.sql
STEP5 后臺(tái)執(zhí)行指令
nohup ./myshell.sh &
3.2.2 結(jié)果
測(cè)試速度相對(duì)快多了坟桅,但是由于第二天就需要华望,所以倆個(gè)表接近4000w行的數(shù)據(jù)絕對(duì)不能完成任務(wù),所以方案取消仅乓。但是不是否定該方案赖舟,其他場(chǎng)景肯定滿足。
3.3 嘗試DMBS
由于我們數(shù)據(jù)庫(kù)是阿里云的RDS夸楣,所以我們購(gòu)買了對(duì)應(yīng)的DBMS服務(wù)升級(jí)版宾抓,可以支持文件上傳導(dǎo)入(包含1G內(nèi)的ZIP)
3.3.1 壓縮文件
壓縮單表SQL文件為單獨(dú)zip文件子漩,壓縮下來(lái)一個(gè)為0.9G,一個(gè)為1.2G
3.3.2 拆分文件
第一個(gè)sql文件上傳后執(zhí)行很順利石洗,但是第二個(gè)1.2G的zip包需要進(jìn)行拆分
3.3.3 拆分方案
1.拆分zip壓縮包
拆分出來(lái)的文件幢泼,手動(dòng)改后綴后不滿足DBMS的文件規(guī)范,失敗~
2.高比例壓縮文件
利用7z高比例壓縮sql為7z后綴讲衫,壓縮后體積明顯小了缕棵,只有0.7G的體積,然后通過(guò)更改后綴為zip來(lái)上傳焦人。結(jié)果阿里云解析不出這樣的格式挥吵,失敗~
3.使用linux split 命令
split [--help][--version][-<行數(shù)>][-b <字節(jié)>][-C <字節(jié)>][-l <行數(shù)>][要切割的文件][輸出文件名]
補(bǔ)充說(shuō)明:
split可將文件切成較小的文件重父,預(yù)設(shè)每1000行會(huì)切成一個(gè)小文件花椭。
-<行數(shù)>或-l<行數(shù)> 指定每多少行就要切成一個(gè)小文件。
-b<字節(jié)> 指定每多少字就要切成一個(gè)小文件房午。支持單位:m,k
-C<字節(jié)> 與-b參數(shù)類似矿辽,但切割時(shí)盡量維持每行的完整性。
雖然linux可以根據(jù)行拆分文件(這也是阿里云工單提供的解決方案)郭厌,但是這個(gè)操作上傳上去拆分袋倔,在下載下來(lái)上傳到DBMS,文件體積這么大折柠,來(lái)來(lái)回回一天過(guò)去了宾娜,所以放棄~
4.拆分單表sql文件為多份
網(wǎng)上有個(gè)SQLDumpSplitter的工具可以拆分表為多份,但是搜索記錄中和文章中都是推薦SQLDumpSplitter2的版本扇售,版本太老了前塔,體積較大的sql完全不支持,失敗~
但是承冰!我在SQLDumpSplitter2里面看到了軟件的官網(wǎng)华弓,發(fā)現(xiàn)官網(wǎng)有SQLDumpSplitter3版本,不抱希望的嘗試了一下困乒,居然支持大體積文件寂屏。成功了!D嚷А迁霎!
附帶下載鏈接:https://philiplb.de/sqldumpsplitter3/ 太值得推廣了。
剩下就是按序上傳對(duì)應(yīng)文件即可完成百宇,不得不得夸阿里云這方面做得真的好考廉!
執(zhí)行效率上面來(lái)說(shuō),也是可圈可點(diǎn)的:
四. 總結(jié)
今天針對(duì)這個(gè)需求恳谎,我首先查詢了網(wǎng)上的大體方案芝此,然后挑選了幾個(gè)可執(zhí)行的方案進(jìn)行測(cè)試憋肖。排除了多個(gè)方案的情況下,采用了第三方的解決方案來(lái)完成這個(gè)問(wèn)題婚苹。在阿里云DBMS的支持下岸更,我們又嘗試了多種文件的切割方案,最后通過(guò)SQLDumpSplitter3+DBMS來(lái)實(shí)現(xiàn)了膊升,并且效率可觀怎炊。過(guò)程中也發(fā)現(xiàn),常用的client-source方案可以滿足自建mysql+效率要求不是極致的場(chǎng)景廓译。
綜上评肆,對(duì)于大型sql,最好的方案也是先切割(確保順序性)非区,然后利用一些更高效率的軟件執(zhí)行來(lái)實(shí)現(xiàn)最終結(jié)果瓜挽,也需要根據(jù)時(shí)間空間場(chǎng)景靈活選用方案。