mysql 跨实例复制数据_社区投稿 | MySQL 跨实例 copy 大表解决方案
作者簡(jiǎn)介
任坤,現(xiàn)居珠海,先后擔(dān)任專職 Oracle 和 MySQL DBA,現(xiàn)在主要負(fù)責(zé) MySQL、mongoDB 和 Redis 維護(hù)工作。
一、背景
某天晚上 20:00 左右開(kāi)發(fā)人員找到我,要求把 pre-prod 環(huán)境上的某張表導(dǎo)入到 prod ,第二天早上 07:00 上線要用。該表有數(shù)億條數(shù)據(jù),壓縮后 ibd 文件大約 25G 左右,表結(jié)構(gòu)比較簡(jiǎn)單:
CREATE TABLE `t` (
`UNIQUE_KEY` varchar(32) NOT NULL,
`DESC` varchar(64) DEFAULT NULL ,
`NUM_ID` int(10) DEFAULT '0' ,
PRIMARY KEY (`UNIQUE_KEY`),
KEY `index_NumID` (`NUM_ID`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED
MySQL 版本:pre-prod 和 prod 都采用 5.7.25 ,單向主從結(jié)構(gòu)。
二、解決方案
最簡(jiǎn)單的方法是采用 mysqldump + source ,但是該表數(shù)量比較多,之前測(cè)試的時(shí)候至少耗時(shí) 4h+ ,這次任務(wù)時(shí)間窗口比較短,如果中間執(zhí)行失敗再重試,可能會(huì)影響業(yè)務(wù)正式上線。采用 select into outfile + load infile 會(huì)快一點(diǎn),但是該方案有個(gè)致命問(wèn)題:該命令在主庫(kù)會(huì)把所有數(shù)據(jù)當(dāng)成單個(gè)事務(wù)執(zhí)行,只有把數(shù)據(jù)全部成功插入后,才會(huì)將 binlog 復(fù)制到從庫(kù),這樣會(huì)造成從庫(kù)嚴(yán)重延遲,而且生成的單個(gè) binlog 大小嚴(yán)重超標(biāo),在磁盤空間不足時(shí)可能會(huì)把磁盤占滿。經(jīng)過(guò)比較,最終采用了可傳輸表空間方案,MySQL 5.6 借鑒 Oracle 引入該技術(shù),允許在 2 個(gè)不同實(shí)例間快速的 copy innodb 大表。該方案規(guī)避了昂貴的 sql 解析和 B+tree 葉節(jié)點(diǎn)分裂,目標(biāo)庫(kù)可直接重用其他實(shí)例已有的 ibd 文件,只需同步一下數(shù)據(jù)字典,并對(duì) ibd 文件頁(yè)進(jìn)行一下校驗(yàn),即可完成數(shù)據(jù)同步操作。
具體操作步驟如下:1. 目標(biāo)庫(kù),創(chuàng)建表結(jié)構(gòu),然后執(zhí)行 ALTER TABLE t DISCARD TABLESPACE ,此時(shí)表t只剩下 frm 文件
2. 源庫(kù),開(kāi)啟 2 個(gè)會(huì)話
session1:執(zhí)行 FLUSH TABLES t FOR EXPORT ,該命令會(huì)對(duì) t 加鎖,將t的臟數(shù)據(jù)從 buffer pool 同步到表文件,同時(shí)新生成 1 個(gè)文件 t.cfg ,該文件存儲(chǔ)了表的數(shù)據(jù)字典信息
session2:保持 session1 打開(kāi)狀態(tài),此時(shí)將 t.cfg 和 t.ibd 遠(yuǎn)程傳輸?shù)侥繕?biāo)庫(kù)的數(shù)據(jù)目錄,如果目標(biāo)庫(kù)是主從結(jié)構(gòu),需要分別傳輸?shù)街鲝膬蓚€(gè)實(shí)例,傳輸完畢后修改屬主為 mysql:mysql
3. 源庫(kù),session1 執(zhí)行 unlock tables ,解鎖表 t ,此時(shí) t 恢復(fù)正常讀寫(xiě)
4. 目標(biāo)庫(kù),執(zhí)行 ALTER TABLE t IMPORT TABLESPACE ,如果是主從結(jié)構(gòu),只需要在主庫(kù)執(zhí)行即可
三、實(shí)測(cè)
針對(duì)該表,執(zhí)行 ALTER TABLE ... IMPORT TABLESPACE 命令只需要 6 分鐘完成,且 IO 消耗和主從延遲都被控制到合理范圍。原本需要數(shù)個(gè)小時(shí)的操作,只需 10 多分鐘完成(算上數(shù)據(jù)傳輸耗時(shí))。如果線上有空表需要一次性加載大量數(shù)據(jù),可以考慮先將數(shù)據(jù)導(dǎo)入到測(cè)試環(huán)境,然后通過(guò)可傳輸表空間技術(shù)同步到線上,可節(jié)約大量執(zhí)行時(shí)間和服務(wù)器資源。
四、總結(jié)
可傳輸表空間,有如下使用限制:源庫(kù)和目標(biāo)庫(kù)版本一致
只適用于 innodb 引擎表
源庫(kù)執(zhí)行 flush tables t for export 時(shí),該表會(huì)不可寫(xiě)
總結(jié)
以上是生活随笔為你收集整理的mysql 跨实例复制数据_社区投稿 | MySQL 跨实例 copy 大表解决方案的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 信用卡停息挂账申请办法
- 下一篇: 拉闸限电背后没有所谓金融战 不要被营销号