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类型(如,修改列的类型、修改列的长度、修改字符集等)无法覆盖。 
适用场景
- 变更数据库表结构。 
- 变更表的字符集和校验集、调整时区等。 
- 规避Optimize Table操作回收表空间、降低碎片率引起的锁表。具体操作,请参见无锁结构变更回收碎片空间。 
支持的数据库类型
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:支持 
 
DMS无锁结构变更与其他变更方案对比信息,请参见无锁结构变更方案对比。
注意事项
- DMS支持对已有分区表的表进行结构变更。 
- 无锁结构变更支持在同一变更工单中,对同一数据库下的多张表进行变更。 - 在配置工单的变更SQL时,不同表SQL可使用英文分号(;)隔开。 
- 当表(只有主键或唯一键)进行无锁表结构变更时,不允许更新主键和唯一键,否则会导致变更任务失败。 
- 美国地域的DMS暂不支持此功能。 
主要原理
当您提交了无锁结构变更工单,DMS会自动进行如下操作,以实现无锁结构变更。
- 创建临时表:DMS在目标数据库中创建与原表结构相同的临时表用于数据拷贝。 - SQL语法为 - CREATE TABLE tmp_table_name LIKE table_name。
- 变更临时表结构: 根据业务需求变更临时表结构。 - SQL语法为 - ALTER TABLE tmp_table_name XXXX。
- 拷贝全量数据:将目标表中的全量数据同步至临时表。 - SQL语法为 - INSERT IGNORE INTO tmp_table_name (SELECT %s FROM table_name FORCE INDEX (%s) WHERE XXX LOCK IN SHARE MODE)。
- 解析Binlog并同步增量数据: 将目标表中的增量数据同步至临时表。 - 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为示例的临时表名。您可以在无锁变更任务进展区域查询具体的临时表名,具体操作,请参见查看无锁变更进度。
如下为具体的临时表名格式:
- 数据表:tp_{变更ID}_ogt_{原表名}、tp_{变更ID}_g_{原表名} 
- 心跳表:tp_{变更ID}_ogl_{原表名}、tp_{变更ID}_l_{原表名} 
- 切换前的辅助表、切换后的原表:tp_{变更ID}_del_{原表名}、tp_{变更ID}_d_{原表名} 
- 探测是否锁表: tpa_xxx_xxx 
变更ID是DMS内部引擎的执行ID,不是工单号和任务号。
相关文档
- 在您了解了无锁结构变更的背景、原理等信息后,您可以进行如下操作: - 给实例开启无锁结构变更功能。具体操作,请参见开启无锁结构变更。 
- 提交无锁结构变更工单。具体操作,请参见通过无锁变更工单实现无锁结构变更。 
- (可选)查看无锁变更任务的进度。具体操作,请参见查看无锁变更进度。 
 
- 您也可以通过API来配置和管理无锁结构变更工单: - API - 说明 - 该接口用于创建无锁变更工单。 - 该接口用于获取无锁变更工单的任务详情,包含任务的执行情况、影响的数据行数。 
常见问题
- Q:无锁结构变更对业务有影响吗? - A:正常情况下不影响您的业务。由于变更过程涉及数据拷贝,会对实例性能产生一定影响。 
- Q:通过无锁变更工单执行CREATE_INDEX添加索引报错了,是DMS不支持添加索引吗? - A:DMS支持添加索引。您可尝试换一种添加索引的方式,例如 - ALTER TABLE `table_name` ADD INDEX index_name ( `column` ) ;