DDL无锁变更有效解决了结构变更时锁表的问题,较好地规避因数据库变更导致锁表以至阻塞业务的问题,以及数据库原生Online DDL带来的主备延迟现象。
背景信息
在大数据量的情况下进行结构变更,需要考虑锁表的风险,锁表将导致业务无法正常写入。MySQL原生能力:- MySQL 5.5及之前的版本,DDL提供了Table-Copy和In-Place两种执行算法:
- Table-Copy:通过拷贝临时表完成变更,变更期间表被锁定不可写入。
- In-Place(从MySQL5.5开始提供):该算法执行期间数据库可以进行读写,但仅支持索引数据。
- MySQL 5.6及后续的版本,DDL还提供了Innodb-OnlineDDL。关于Innodb-OnlineDDL,请参见Innodb-OnlineDDL。
可以覆盖大范围的DDL类型(如,添加列、删除列、列名修改、添加索引、修改索引等),但仍然有些常见的DDL类型(如,修改列的类型、修改列的长度、修改字符集等)无法覆盖。
支持的数据库类型
RDS MySQL、PolarDB MySQL版、MyBase MySQL、其他来源MySQL。
功能特点
- 相比较数据库原生,DMS无锁结构变更支持控制变更的执行速率,可避免数据库主备链路延迟,对数据库性能影响更小,并支持多种原生OnlineDDL执行时会锁表的场景。
- 相比较PT-Online、OSC等其它工具,DMS无锁结构变更不依赖于触发器,且异步执行时对数据库的影响非常小,可随时安全中断。
- DMS无锁结构变更与DTS同步工具兼容性好,变更的表中如有DTS表级别的复制链路,使用DMS无锁结构变更不会导致DTS复制中断。说明 必须在2020年2月14日后重启过DTS复制链路。
- MySQL原生OnlineDDL与DMS无锁结构变更能力对比:
支持项 MySQL5.5及以前版本 MySQL5.6及后续版本 DMS无锁结构变更 添加列 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 转换字符 N N Y 时区修正操作 N N Y 缓解或消除备库延迟 N N Y - N:不支持。
- Y:支持
主要原理
- 创建临时表:CREATE TABLE tmp_table_table LIKE table_name。
- 变更临时表结构: ALTER TABLE tmp_table_table XXXX。
- 全量拷贝数据:INSERT IGNORE INTO tmp_table_table (SELECT %s FROM table_name FORCE INDEX (%s) WHERE xxx。
- 增量数据Binlog同步: UPDATE/INSERT/DELETE tmp_table_name。
- 切换新旧表: RENAME TABLE table_name to old_tmp_table_table, tmp_table_name to table_name。
DMS生成的临时表名规则:
- 数据表:tp_{变更ID}_ogt_{原表名}、tp_{变更ID}_g_{原表名}
- 心跳表:tp_{变更ID}_ogl_{原表名}、tp_{变更ID}_l_{原表名}
- 切换前的辅助表、切换后的原表:tp_{变更ID}_del_{原表名}、tp_{变更ID}_d_{原表名}
说明 变更ID是DMS内部引擎的执行ID,不是工单号和任务号。
适用场景
- 变更数据库表结构。
- 变更表的字符集、校验集,调整时区等。
- 规避Optimize Table操作回收表空间、降低碎片率时引起的锁表。具体操作,请参见无锁结构变更回收碎片空间。