MySQL 8大表在线DDL变更:pt-osc与gh-ost工具对比与实战选型

在线DDL变更的痛点

MySQL 8虽然支持了ALGORITHM=INPLACE的DDL,但在大表(千万行以上)场景仍然面临锁等待和主从延迟风险。加字段、改索引这类操作,Online DDL期间的主库写负载和从库回放延迟足以拖垮整个业务链路。生产环境必须用第三方工具做影子表切换,实现接近零停机的Schema变更。

pt-online-schema-change工作原理

Percona Toolkit的pt-osc是最成熟的方案,核心流程:

  1. 创建与原表结构相同的影子表
  2. 在影子表上执行DDL
  3. 创建三个Trigger(INSERT/UPDATE/DELETE)将原表的增量变更同步到影子表
  4. 分批从原表拷贝数据到影子表
  5. RENAME TABLE原子切换原表和影子表
  6. 删除旧表和Trigger

加字段操作示例:

pt-online-schema-change   --host=10.0.0.1   --port=3306   --user=admin   --password='S3cureP@ss'   --alter="ADD COLUMN last_login_time DATETIME DEFAULT NULL COMMENT '最后登录时间', ADD INDEX idx_last_login(last_login_time)"   --database=production   --table=users   --max-load=Threads_running=100   --critical-load=Threads_running=200   --chunk-size=1000   --chunk-time=0.5   --recursion-method=processlist   --check-replication-filters   --check-slave-lag=h=slave1,port=3306   --max-lag=2s   --execute

关键参数解析:

  • --max-load:达到100个并发线程时暂停拷贝
  • --critical-load:达到200个并发线程时终止操作
  • --chunk-time=0.5:动态调整每批数据量,目标0.5秒拷完一批
  • --max-lag=2s:从库延迟超2秒暂停拷贝

gh-osc工作原理与差异

GitHub开源的gh-osc不用Trigger做增量同步,而是通过解析binlog回放到影子表。这避免了Trigger带来的性能开销和元数据锁问题。

gh-ost   --host=10.0.0.1   --port=3306   --user=admin   --password='S3cureP@ss'   --database=production   --table=users   --alter="ADD COLUMN last_login_time DATETIME DEFAULT NULL, ADD INDEX idx_last_login(last_login_time)"   --max-load=Threads_running=100   --critical-load=Threads_running=200   --chunk-size=1000   --max-lag-millis=2000   --allow-on-master   --execute

两个工具的场景选型

对比维度 pt-osc gh-ost
增量同步方式 Trigger Binlog解析
对主库性能影响 较高(Trigger开销) 较低
外键支持 支持 不支持
要求binlog格式 无要求 ROW格式
单主机模式 支持 需–allow-on-master
暂停恢复 信号控制 信号+标记文件
RENAME风险 两个RENAME 单RENAME(更安全)

选型建议:

  • 表有外键约束 → pt-osc
  • 主库写入量极大 → gh-ost
  • binlog格式不是ROW且无法修改 → pt-osc
  • 有暂停/恢复的精细控制需求 → gh-ost

变更操作的标准流程

生产环境DDL变更必须遵循以下步骤:

# 1. 在测试环境验证DDL语法
mysql -h test-db -e "SHOW CREATE TABLE users\G"
pt-online-schema-change --dry-run --alter="..." ...

# 2. 在从库验证变更影响
# 先在延迟从库执行,观察主从延迟

# 3. 生产环境执行,开启监控
pt-online-schema-change --execute --alter="..." ... &
# 另开终端监控
watch -n 5 'mysql -e "SHOW PROCESSLIST" | grep pt_osc'

# 4. 变更完成后的验证
mysql -e "SHOW CREATE TABLE users\G"
mysql -e "SELECT COUNT(*) FROM users"
# 检查Trigger是否已清理
mysql -e "SHOW TRIGGERS FROM production LIKE 'users'"

大表DDL不是难在技术实现,难在操作纪律。变更窗口审批、从库延迟监控、回滚方案准备——这三样缺一不可。工具再好,操作不规范一样出事故。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/mysql8-da-biao-zai-xian-ddl-bian-geng-ptosc-yu-ghost-gong/

(0)
小编小编
上一篇 12小时前
下一篇 12小时前

相关推荐