DMS为解决结构变更时的锁表问题推出了无锁结构变更功能,较好地规避因数据库变更导致锁表以至于阻塞业务的现象,以及数据库原生Online DDL带来的主备延迟现象。

前提条件

实例的管控模式为稳定变更或安全协同。

背景信息

诸多业务在研发之初都会采用MySQL作为数据库的技术选型。随着业务的发展,数据量不断增加,MySQL的维护难度越来越高。在大数据量的情况下去做结构变更(增加字段、修改字段属性、增加索引、修改索引等)需要考虑锁表的风险,锁表将导致业务无法正常写入。

MySQL原生能力:
  • 在MySQL5.5以及之前的版本中,MySQL的DDL仅提供Table-Copy和In-Place(MySQL5.5开始提供)两种执行算法。
    • Table-Copy:通过拷贝临时表完成变更,变更期间表被锁定不可写入。
    • In-Place:在添加、修改索引时,In-Place会避免源表数据的拷贝操作只对索引数据进行,从而达到变更数据的目的。该算法执行期间可以读写数据,但仅支持索引操作。
  • MySQL5.6及后续版本提供了Innodb-OnlineDDL能力,覆盖了大范围的DDL类型(添加列、删除列、列名修改、添加索引、修改索引等),但仍然有些常见的DDL类型无法覆盖(修改列的类型、修改列的长度、修改字符集等)。

MySQL原生的OnlineDDL在进行结构变更时仍有锁表风险,为了解决这个问题,DMS提供了无锁结构变更功能。

产品优点

  • 相比较数据库原生,DMS无锁结构变更支持控制变更的执行速率,可避免数据库主备链路延迟,对数据库性能影响更小,并支持多种原生OnlineDDL执行时会锁表的场景。
  • 相比较PT-Online(PT-Online-Schema-Change)、OSC(OnlineSchemaChange)等其它工具,DMS无锁结构变更不依赖于触发器,且异步执行时对数据库的影响非常小,可随时安全中断。
  • DMS无锁结构变更与DTS同步工具兼容性好,变更的表中如有DTS表级别的复制链路,使用DMS无锁结构变更不会导致DTS复制中断。
    说明 必须与2020年2月14日后重启过DTS复制链路。
  • MySQL原生OnlineDDL与DMS无锁结构变更能力对比如下。
    支持项 MySQL5.5及以前版本 MySQL5.6及后续版本 DMS无锁结构变更
    添加列 X
    删除列 X
    列名修改 X
    添加索引 X
    修改索引 X
    碎片整理操作 X
    修改列的类型 X X
    修改列的长度 X X
    修改字符集 X X
    转换字符 X X
    分区表操作 X X
    时区修正操作 X X
    缓解或消除备库延迟 X X

主要原理

通过如下动作实现无锁结构变更

  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

典型应用场景

  • 规避数据库变更发生锁表,导致业务阻塞。
  • 规避原生OnlineDDL带来的主备延迟。
  • 规避Optimize Table操作回收表空间、降低碎片率时引起的锁表,具体操作,请参见无锁结构变更回收碎片空间
  • 修改表的字符集、校验集,调整时区等。

功能限制

限制项 说明
数据库版本 MySQL所有版本、PolarDB
数据库引擎 InnoDB、Rocksdb
实例来源 经典网络的RDS、VPC网络的RDS、经典网络的ECS自建数据库、VPC网络的ECS自建数据库、公网自建数据库
管控模式 稳定变更、安全协同
账号权限 必须是以下三种类型账号的其中之一:
  • 高权限账号。
  • 具有日志权限的账号。
  • 读写账号。
磁盘空间 由于需要在目标数据库新建表拷贝数据,大表变更时需要保证磁盘有足够的剩余空间。
说明 RDS实例空间不足将导致实例被锁定。
日志格式 开启Binlog日志。
说明 PolarDB默认未开启Binlog,开启的具体操作,请参见 PolarDB-如何开启Binlog
源表上有主键或唯一键 在执行无锁结构变更时,主键或唯一键将用于全量拷表分段操作及后续增量更新的依据。
  • 如果表上仅有主键:在执行变更期间,不能更新(UPDATE)主键,否则将导致任务失败并退出。
  • 如果表上没有主键,有唯一键:在执行变更期间,不能更新(UPDATE)唯一键,否则将导致任务失败并退出。
  • 如果表上没有主键和唯一键:请在实例上先添加主键或唯一键后,重新提交无锁结构更变任务。

步骤一:开启DMS无锁结构变更优先功能

本步骤的操作需要DBA角色、管理员角色才能执行。

  1. 登录新版DMS控制台
  2. 在页面顶部,选择全部功能 > 系统管理 > 实例管理
  3. 单击目标实例右侧操作列下的更多>编辑实例,打开编辑实例对话框。
  4. 单击高级信息
  5. 不锁表结构变更的下拉菜单中选择开启(DMS无锁表结构变更优先)
    选择项 执行说明 备注
    DMS无锁表结构变更优先 直接使用DMS自研的无锁结构变更执行,以保障不锁表。 执行时间相对MySQL原生OnlineDDL会慢一些,但不影响复制行为,不会产生延迟现象。
    MySQL原生OnlineDDL优先 优先使用MySQL原生的OnlineDDL执行,如果源生会锁表的话会转用DMS自研的无锁结构变更执行,以保障不锁表。 执行时间相对比较快,但有可能导致实例的并行复制降为串行复制,从而可能产生主备延迟现象。
    关闭 原生语句下发给MySQL执行,不进行任何处理。
  6. 单击提交

步骤二:执行数据变更

当您的实例已开启DMS无锁表结构变更优先,您再通过以下方式执行数据变更,均会以无锁的方式进行。
  • 结构设计,具体操作,请参见结构设计
    说明 稳定变更模式的实例如需使用结构设计功能,请提交工单
  • 无锁变更,具体操作,请参见无锁变更
  • 任务管理:DBA和管理员角色可以直接新建任务,选择数据库部署SQL脚本任务。

步骤三:无锁结构变更过程管控

在无锁结构变更任务执行时,数据Owner可通过如下步骤进行管控。

  1. 登录新版DMS控制台
  2. 在页面顶部,选择全部功能 > 系统管理 > 任务管理
    进入任务管理页面。
  3. 单击目标任务号,进入任务执行详情页。
  4. 单击目标任务操作列下的进度按钮。
    说明 您也可以在当前页面下查看脚本语句或执行日志,或选择跳过该任务或修复任务
  5. 无锁结构变更页,查看当前的整体拷贝进度。
    说明 如果您的业务特殊,需要额外配置单次拷贝大小,可以联系售后了解该功能。

附录

请参见无锁结构变更附录