pt-online-schema-change是mysql 5.7大表改结构唯一靠谱方案,因原生alter table多触发全表拷贝致长时间锁表;执行前须满足四大硬性条件:主键或唯一非空索引、无现有触发器、用户具备trigger/replication slave/process权限、外键引用时指定--alter-foreign-keys-method;生产需调优--chunk-time=0.3~0.5、--max-load="threads_running=25"等参数控负载;异常中断后须手动清理残留触发器并用pt-table-checksum校验数据一致性。

pt-online-schema-change 是 MySQL 5.7 大表改结构唯一靠谱的选择——原生 ALTER TABLE 在绝大多数场景下会触发全表拷贝(ALGORITHM=COPY),锁表时间动辄几十分钟,业务直接不可用。
pt-online-schema-change 执行前必须过掉的四个硬检查
漏掉任一条件,工具会直接退出或导致数据错乱:
- 原表必须有主键或唯一非空索引,否则报错:
Cannot chunk table <code>db.t: no primary key or unique not-null index - 原表不能已有任何触发器,否则提示:
Triggers exist on the table - 操作用户必须显式拥有:
TRIGGER、REPLICATION SLAVE、PROCESS权限(仅SELECT/INSERT/UPDATE/DELETE不够) - 若该表被其他表外键引用,必须加参数:
--alter-foreign-keys-method=auto或--alter-foreign-keys-method=rebuild_constraints,否则RENAME阶段失败
--chunk-time 和 --max-load 怎么配才不拖垮线上库
默认参数只适合本地测试,生产环境必须调;目标不是“快”,而是“不抢资源”:
-
--chunk-time=0.3~0.5:控制每批拷贝耗时(秒),值越小,单次 IO/CPU 负载越平缓 - 别碰
--chunk-size:它由--chunk-time动态反推,手动设死反而容易打爆缓冲区 -
--max-load="Threads_running=25":当SHOW STATUS LIKE 'Threads_running'超过 25 时自动暂停,防连接池雪崩 -
--critical-load="Threads_running=50":达到即中止,避免 DB 彻底卡死 -
--check-interval=5:每 5 秒检查一次负载,配合--max-load生效 -
--max-lag=1:从库延迟超 1 秒就暂停拷贝,防止复制中断
异常中断后最容易被忽略的两件事
很多翻车不是命令写错,而是收尾没做干净:
- 中断后原表上可能残留触发器:
pt_osc_db_t1_del、pt_osc_db_t1_ins、pt_osc_db_t1_upd,必须手动清理:DROP TRIGGER IF EXISTS pt_osc_db_t1_del(把db和t1替成实际值) - 表名替换完成后,工具虽自动
RENAME并删旧表,但必须人工核对:字段类型、索引定义、字符集是否和预期一致;再用pt-table-checksum校验数据一致性——仅靠COUNT(*)不可靠,触发器同步期间可能有极少量延迟
真正麻烦的从来不是执行过程,而是你以为结束了,其实触发器还挂着、旧表还占着空间、索引缺失没发现。











