MySQL 大表在线 DDL 怎么做:加字段、主从延迟和 pt-osc 风险

4次阅读
没有评论

MySQL 小表加字段通常没什么感觉,一条 alter table add column 很快结束。但如果表有几千万、上亿行,DDL 就变成一次生产变更。它可能锁表、撑爆临时空间、制造主从延迟,甚至拖慢线上写入。

所以大表在线 DDL 不是“会不会写 SQL”的问题,而是变更风险控制问题。

先确认表和业务状态

动大表前,至少要确认这些信息:

  • 表数据量和索引数量。
  • 当前 MySQL 版本。
  • 存储引擎是否为 InnoDB。
  • 表上有没有外键和触发器。
  • 当前有没有大事务。
  • 磁盘空间是否足够。
  • 主从复制延迟是否稳定。
  • 业务低峰窗口在哪里。

这些信息会影响 DDL 方式选择。如果表很小,直接执行就行;如果表巨大,就要考虑在线 DDL、从库先变更、pt-online-schema-change 或 gh-ost 等方案。

MySQL 原始 DDL 为什么危险

早期 InnoDB 做 DDL 时,可能会创建临时表,把原表数据复制过去,再 rename 替换。这个过程会涉及大量 IO、临时空间和锁。

简化流程类似:

  1. 按新结构创建临时表。
  2. 从原表复制数据到临时表。
  3. 维护索引。
  4. rename 新旧表。
  5. 删除旧表。

如果过程中持有写锁,线上写入就会被阻塞。即使支持 Online DDL,也要看具体操作是否真的能 INPLACE、是否允许 LOCK=NONE

Online DDL 也要看算法和锁

MySQL DDL 常见参数包括:

alter table t
  add column c varchar(32),
  algorithm=inplace,
  lock=none;

需要关注:

  • algorithm=copy:通常需要复制表,风险大。
  • algorithm=inplace:尽量原地变更,但不是所有操作都支持。
  • lock=none:尽量不阻塞读写。
  • lock=shared:允许读,限制写。
  • lock=exclusive:读写都可能被阻塞。

不要只看到“Online DDL”四个字就放心。真正执行前要结合版本、操作类型和执行计划判断。

主从架构下要考虑复制延迟

如果直接在主库上执行大 DDL,主库执行完后,binlog 会传给从库。从库 SQL 线程通常按顺序执行,DDL 如果耗时很久,后面的复制事件就会排队,主从延迟可能迅速变大。

一种思路是先在从库变更,再做主从切换,最后处理原主库。大致步骤是:

  1. 停止从库复制。
  2. 从库关闭 binlog 或避免写入复制链路。
  3. 在从库执行 DDL。
  4. 恢复复制并观察延迟。
  5. 做主从切换。
  6. 在原主库执行同样 DDL。

这类方案要配合成熟的主从切换工具和回滚预案,不适合临时手工乱操作。

pt-online-schema-change 的原理

pt-online-schema-change 是经典在线改表工具。它的核心不是直接改原表,而是创建一张新表,然后慢慢搬数据。

大致流程:

  1. 创建一张和原表结构相同的新表。
  2. 在新表上执行目标 DDL。
  3. 在原表上创建 insert、update、delete 触发器。
  4. 分批把原表数据复制到新表。
  5. 复制过程中用触发器同步增量变更。
  6. 最后 rename 表,把新表替换成原表。
  7. 删除触发器和旧表。

它的好处是降低长时间锁表风险,坏处是引入触发器、额外写入、额外空间和 rename 切换风险。

pt-osc 不是无脑安全

pt-osc 有几个常见限制:

  • 表上已有触发器时会冲突。
  • 外键表需要额外参数和判断。
  • 表写入压力大时,触发器会增加负担。
  • 需要额外磁盘空间保存新表。
  • rename 切换瞬间仍需要元数据锁。

所以用 pt-osc 前,要先 dry-run,并确认主键、外键、触发器、磁盘、复制延迟和业务峰值。

加字段前的检查清单

一个比较稳的检查顺序:

  1. 确认字段是否真的需要立即加。
  2. 确认默认值是否会触发表重写。
  3. 确认字段是否允许 NULL。
  4. 确认是否需要同时加索引。
  5. 确认 DDL 算法和锁级别。
  6. 确认磁盘空间和临时目录。
  7. 确认主从延迟和大事务。
  8. 准备回滚和暂停策略。
  9. 低峰执行。
  10. 执行后观察慢查询、复制延迟和业务错误。

字段变更不要和索引变更、大批量回填、代码发布混在一次不可控变更里。能拆就拆,先加 nullable 字段,再灰度写入,再回填,再加约束。

最后看取舍

小表直接改,大表先评估。Online DDL、pt-osc、从库先变更都不是银弹,它们只是不同风险之间的取舍。

真正重要的是:执行前知道会不会锁、会不会复制延迟、会不会占空间;执行中能观察;执行后能验证;出问题能停下来。

正文完
 0
bdspAdmin
版权声明:本站原创文章,由 bdspAdmin 于2026-06-30发表,共计1732字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)