gh-ost 与 pt-online-schema-change 对比:原理、流程与选型指南
核心结论一句话总结
gh-ost 更安全、更智能、更现代,适合大规模生产环境(由阿里推动开源);
pt-online-schema-change 功能成熟、兼容性广,是老牌可靠工具(Percona 出品)。
核心对比维度
| 对比项 |
gh-ost |
pt-online-schema-change |
| 开发者 |
阿里(GitHub 开源) |
Percona |
| 实现原理 |
基于 binlog 订阅 + 自建 relay log 实现流控同步 |
依赖数据库触发器进行实时数据同步 |
| 对主库性能影响 |
低(无需触发器,压力小) |
高(所有写操作均触发额外逻辑) |
| 执行风险 |
低(无触发器崩溃风险) |
中等(触发器异常可能导致阻塞) |
| 回滚能力 |
强(支持强制中断和暂停) |
一般(触发器模式下难以快速回退) |
| 监控能力 |
强(提供 QPS、延迟、复制进度等指标) |
弱(缺乏细粒度观测手段) |
| 使用体验 |
现代化设计,参数清晰友好 |
配置复杂,学习成本较高 |
| 版本兼容性 |
MySQL 5.6 及以上 |
支持 MySQL 全版本 |
| 适用场景 |
大表(>5000万行)、主从架构、高安全性要求系统 |
中等规模表、对触发器不敏感的业务系统 |
最终建议:企业级应用或大数据量场景优先选择 gh-ost;普通变更且环境受限时可选用 pt-osc。
二、核心实现原理详解
1. pt-online-schema-change:基于触发器的数据同步
该工具通过在原表上创建触发器来保证新旧表数据一致,具体流程如下:
- 创建一个新的 ghost 表,结构为目标 schema
- 在原表上建立三个触发器(INSERT、UPDATE、DELETE)
- 每次原表发生写入操作时,自动将变更同步至 ghost 表
- 后台任务分批将原表历史数据迁移至 ghost 表
- 数据迁移完成后,短暂获取元数据锁(metadata lock)
- 原子 rename 操作替换原表
- 清理旧表及触发器
[此处为图片1]
优点:
- 历史悠久,稳定性经过长期验证
- 支持所有类型的 ALTER TABLE 操作
- 兼容各种 MySQL 版本和部署方式
缺点:
- 高并发写入下触发器成为性能瓶颈
- 显著增加主库负载,可能引发复制延迟
- 大表操作存在较大风险
- 出错后回滚困难,需人工干预
2. gh-ost:基于 binlog 的流式复制机制
gh-ost 的最大创新在于完全摒弃了触发器,转而利用 binlog 实现增量同步。其工作流程如下:
- 创建目标结构的 ghost 表
- 连接 MySQL 并开启 binlog 流订阅(类似 Canal 或 Maxwell)
- 捕获原表所有的增删改操作(DML)
- 将这些变更事件实时应用到 ghost 表中
- 后台按主键分页批量迁移存量数据
- 根据从库复制延迟动态调整迁移速度(自适应限流)
- 待全量+增量数据一致后,短暂加 metadata lock
- 执行 rename 原子切换表名
- 清除旧表
[此处为图片2]
优点:
- 零触发器,极大降低主库压力
- 具备自适应节流能力,保障系统稳定
- 支持暂停、恢复、预演等多种安全模式
- 对主库影响极小,适合线上高频交易系统
- 提供详细的进度与延迟监控信息
缺点:
- 必须依赖 MySQL 主从复制架构
- 部分复杂的 DDL 不被支持
- 在 MySQL 8.0 的某些配置下可能存在兼容问题
三、实际执行流程示例
pt-online-schema-change 执行命令示例
pt-online-schema-change \
--alter "ADD COLUMN age INT" \
D=test,t=user \
--execute
内部执行动作包括:
- 创建新表(符合修改后的结构)
- 在原表添加 INSERT/UPDATE/DELETE 触发器
- 启动后台线程逐步拷贝旧数据
- 触发器确保期间写入同步到新表
- 完成拷贝后短暂停写并切换表名
- 删除旧表与触发器
gh-ost 常用执行方式(推荐在从库运行)
gh-ost \
--allow-on-master \
--host=127.0.0.1 \
--user=root \
--database=test \
--table=user \
--alter="ADD COLUMN age INT" \
--execute
内部主要行为:
- 连接数据库并开始监听 binlog 事件流
- 解析原表的每一项 DML 操作
- 异步将变更写入 ghost 表
- 以主键为依据分批次迁移历史数据
- 根据复制延迟自动调节迁移速率
- 最终完成表名切换并清理资源
[此处为图片3]
四、何时必须选择 gh-ost?
以下场景强烈建议使用 gh-ost:
- 单表行数超过 3000 万甚至上亿
- 表更新频繁(QPS > 1000)
- 系统不允许出现明显性能波动(如电商、金融类业务)
- 采用标准主从复制架构
- 需要精细化控制迁移过程(限流、暂停、监控)
原因说明:pt-osc 使用的触发器机制在高并发环境下会显著加重主库负担,容易导致服务抖动或延迟累积。
五、何时更适合使用 pt-online-schema-change?
以下情况推荐继续使用 pt-osc:
- 未开启 binlog 或 binlog_format 非 ROW 模式
- 表写入频率很低,变更稀疏
- 使用较老版本 MySQL(低于 5.6)
- 所需执行的 DDL 类型 gh-ost 不支持
- 系统对性能变化容忍度较高
面试高频总结句(必背)
gh-ost 采用 binlog 订阅机制实现无触发器在线改表,避免了传统方案对主库的性能冲击,更适合超大表和高可用场景;而 pt-online-schema-change 虽依赖触发器带来一定负载,但兼容性强,适用于各类常规环境。两者各有定位,关键看数据规模与系统要求。