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 MySQLPolarDB 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无锁结构变更
    添加列NYY
    删除列NYY
    列名修改NYY
    添加索引NYY
    修改索引NYY
    碎片整理操作NYY
    修改列的类型NNY
    修改列的长度NNY
    修改字符集NNY
    转换字符NNY
    时区修正操作NNY
    缓解或消除备库延迟NNY
    • N:不支持。
    • Y:支持
更多信息,请参见无锁结构变更方案对比

主要原理

  1. 创建临时表:CREATE TABLE tmp_table_table LIKE table_name。
  2. 变更临时表结构: ALTER TABLE tmp_table_table XXXX。
  3. 全量拷贝数据:INSERT IGNORE INTO tmp_table_table (SELECT %s FROM table_name FORCE INDEX (%s) WHERE xxx。
  4. 增量数据Binlog同步: UPDATE/INSERT/DELETE tmp_table_name。
  5. 切换新旧表: 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操作回收表空间、降低碎片率时引起的锁表。具体操作,请参见无锁结构变更回收碎片空间