無鎖結(jié)構(gòu)變更
DDL無鎖變更能夠有效解決結(jié)構(gòu)變更時鎖表的問題,較好地規(guī)避了因鎖表導(dǎo)致業(yè)務(wù)阻塞的問題、避免了數(shù)據(jù)庫原生Online DDL帶來的主備延遲現(xiàn)象。您可在業(yè)務(wù)低峰期提交無鎖變更。
背景信息
在數(shù)據(jù)量大的情況下進(jìn)行結(jié)構(gòu)變更,需要考慮鎖表的風(fēng)險(xiǎn),鎖表將導(dǎo)致業(yè)務(wù)無法正常寫入。MySQL原生能力:
MySQL 5.5及之前的版本,DDL提供了Table-Copy和In-Place兩種執(zhí)行算法:
Table-Copy:通過拷貝臨時表完成變更,變更期間表被鎖定不可寫入。
In-Place(從MySQL5.5開始提供):該算法執(zhí)行期間數(shù)據(jù)庫可以進(jìn)行讀寫,但僅支持索引數(shù)據(jù)。
MySQL 5.6及后續(xù)的版本,DDL還提供了Innodb-OnlineDDL。關(guān)于Innodb-OnlineDDL,請參見Innodb-OnlineDDL。
可以覆蓋大范圍的DDL類型(如,添加列、刪除列、列名修改、添加索引、修改索引等),但仍然有些常見的DDL類型(如,修改列的類型、修改列的長度、修改字符集等)無法覆蓋。
適用場景
變更數(shù)據(jù)庫表結(jié)構(gòu)。
變更表的字符集和校驗(yàn)集、調(diào)整時區(qū)等。
規(guī)避Optimize Table操作回收表空間、降低碎片率引起的鎖表。具體操作,請參見無鎖結(jié)構(gòu)變更回收碎片空間。
支持的數(shù)據(jù)庫類型
RDS MySQL、PolarDB MySQL版、MyBase MySQL、其他來源MySQL。
功能特點(diǎn)
相比較數(shù)據(jù)庫原生,DMS無鎖結(jié)構(gòu)變更支持控制變更的執(zhí)行速率,可避免數(shù)據(jù)庫主備鏈路延遲,對數(shù)據(jù)庫性能影響更小,并支持多種原生OnlineDDL執(zhí)行時會鎖表的場景。
相比較PT-Online、OSC等其他工具,DMS無鎖結(jié)構(gòu)變更不依賴于觸發(fā)器,且異步執(zhí)行時對數(shù)據(jù)庫的影響非常小,可隨時安全中斷。
DMS無鎖結(jié)構(gòu)變更與DTS同步工具兼容性好,變更的表中如有DTS表級別的復(fù)制鏈路,使用DMS無鎖結(jié)構(gòu)變更不會導(dǎo)致DTS復(fù)制中斷。
說明必須在2020年2月14日后重啟過DTS復(fù)制鏈路。
MySQL原生OnlineDDL與DMS無鎖結(jié)構(gòu)變更能力對比:
支持項(xiàng)
MySQL5.5及以前版本
MySQL5.6及后續(xù)版本
DMS無鎖結(jié)構(gòu)變更
添加列
N
Y
Y
刪除列
N
Y
Y
列名修改
N
Y
Y
添加索引
N
Y
Y
修改索引
N
Y
Y
碎片整理操作
N
Y
Y
修改列的類型
N
N
Y
修改列的長度
N
N
Y
修改字符集
N
N
Y
轉(zhuǎn)換字符
N
N
Y
時區(qū)修正操作
N
N
Y
緩解或消除備庫延遲
N
N
Y
N:不支持。
Y:支持
DMS無鎖結(jié)構(gòu)變更與其他變更方案對比信息,請參見無鎖結(jié)構(gòu)變更方案對比。
注意事項(xiàng)
DMS支持對已有分區(qū)表的表進(jìn)行結(jié)構(gòu)變更。
無鎖結(jié)構(gòu)變更支持在同一變更工單中,對同一數(shù)據(jù)庫下的多張表進(jìn)行變更。
在配置工單的變更SQL時,不同表SQL可使用英文分號(;)隔開。
當(dāng)表(只有主鍵或唯一鍵)進(jìn)行無鎖表結(jié)構(gòu)變更時,不允許更新主鍵和唯一鍵,否則會導(dǎo)致變更任務(wù)失敗。
主要原理
當(dāng)您提交了無鎖結(jié)構(gòu)變更工單,DMS會自動進(jìn)行如下操作,以實(shí)現(xiàn)無鎖結(jié)構(gòu)變更。
創(chuàng)建臨時表:DMS在目標(biāo)數(shù)據(jù)庫中創(chuàng)建與原表結(jié)構(gòu)相同的臨時表用于數(shù)據(jù)拷貝。
SQL語法為
CREATE TABLE tmp_table_name LIKE table_name
。變更臨時表結(jié)構(gòu): 根據(jù)業(yè)務(wù)需求變更臨時表結(jié)構(gòu)。
SQL語法為
ALTER TABLE tmp_table_name XXXX
。拷貝全量數(shù)據(jù):將目標(biāo)表中的全量數(shù)據(jù)同步至臨時表。
SQL語法為
INSERT IGNORE INTO tmp_table_name (SELECT %s FROM table_name FORCE INDEX (%s) WHERE xxx
。解析Binlog并同步增量數(shù)據(jù): 將目標(biāo)表中的增量數(shù)據(jù)同步至臨時表。
SQL語法為
UPDATE/INSERT/DELETE tmp_table_name
。切換新舊表:重命名原表作為備份,再用臨時表替換原表。
SQL語法為
RENAME TABLE table_name to old_tmp_table_name, tmp_table_name to table_name
。
tmp_table_name為示例的臨時表名。您可以在無鎖變更任務(wù)進(jìn)展區(qū)域查詢具體的臨時表名,具體操作,請參見查看無鎖變更進(jìn)度。
如下為具體的臨時表名格式:
數(shù)據(jù)表:tp_{變更ID}_ogt_{原表名}、tp_{變更ID}_g_{原表名}
心跳表:tp_{變更ID}_ogl_{原表名}、tp_{變更ID}_l_{原表名}
切換前的輔助表、切換后的原表:tp_{變更ID}_del_{原表名}、tp_{變更ID}_d_{原表名}
探測是否鎖表: tpa_xxx_xxx
變更ID是DMS內(nèi)部引擎的執(zhí)行ID,不是工單號和任務(wù)號。
相關(guān)文檔
在您了解了無鎖結(jié)構(gòu)變更的背景、原理等信息后,您可以進(jìn)行如下操作:
給實(shí)例開啟無鎖結(jié)構(gòu)變更功能。具體操作,請參見開啟無鎖結(jié)構(gòu)變更。
提交無鎖結(jié)構(gòu)變更工單。具體操作,請參見通過無鎖變更工單實(shí)現(xiàn)無鎖結(jié)構(gòu)變更。
(可選)查看無鎖變更任務(wù)的進(jìn)度。具體操作,請參見查看無鎖變更進(jìn)度。
您也可以通過API來配置和管理無鎖結(jié)構(gòu)變更工單:
API
說明
該接口用于創(chuàng)建無鎖變更工單。
該接口用于獲取無鎖變更工單的任務(wù)詳情,包含任務(wù)的執(zhí)行情況、影響的數(shù)據(jù)行數(shù)。
常見問題
Q:無鎖結(jié)構(gòu)變更對業(yè)務(wù)有影響嗎?
A:正常情況下不影響您的業(yè)務(wù)。由于變更過程涉及數(shù)據(jù)拷貝,會對實(shí)例性能產(chǎn)生一定影響。
Q:通過無鎖變更工單執(zhí)行CREATE_INDEX添加索引報(bào)錯了,是DMS不支持添加索引嗎?
A:DMS支持添加索引。您可嘗試換一種添加索引的方式,例如?
ALTER TABLE `table_name` ADD INDEX index_name ( `column` ) ;