必须用pt-online-schema-change而非直接ALTER TABLE,因后者在MySQL 5.7中强制COPY算法,全程MDL锁、10GB表可能锁表半小时以上;pt-osc通过影子表+触发器实现无锁迁移,但需满足主键/无触发器/权限/外键处理四大前提。

直接改引擎必须用 pt-online-schema-change,原生 ALTER TABLE ... ENGINE=InnoDB 在 MySQL 5.7 中仍会全表拷贝并锁死 DML,10GB 表可能卡住半小时以上。
为什么不能只写 ALTER TABLE t1 ENGINE=InnoDB?
因为 pt-online-schema-change 的 --alter 参数只要求填「变更内容」,不是完整 SQL。写成 --alter "ALTER TABLE t1 ENGINE=InnoDB" 会报语法错误;正确写法是 --alter "ENGINE=InnoDB"。
常见错误现象:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 命令执行直接退出,提示
Syntax error: unknown keyword 'ALTER' - 误以为工具不支持改引擎,其实是参数格式错了
执行前必须满足的四个硬性条件
漏掉任一,工具会拒绝启动或中途失败:
- 原表必须有主键或唯一非空索引,否则报错:
Cannot chunk table `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,否则RENAME阶段失败
--chunk-time 和 --max-lag 怎么设才稳?
默认参数只适合测试库,生产环境必须调。重点不是快,而是不让从库延迟飙升、不让主库连接池打满:
-
--chunk-time=0.4:控制每批拷贝耗时上限(秒),值越小对 IO/CPU 冲击越小;10GB 表建议 0.3~0.5,别碰--chunk-size——它由--chunk-time动态反推 -
--max-lag=1:从库延迟超 1 秒就暂停拷贝,防止复制中断;MySQL 5.7 默认监控Seconds_Behind_Master -
--max-load="Threads_running=25":主库活跃线程超 25 就暂停,避免连接雪崩 -
--critical-load="Threads_running=50":达到即中止,防止 DB 彻底卡死
执行完最容易被忽略的收尾动作
很多线上事故不是出在执行过程,而是收尾没做干净:
- 异常中断后,原表上可能残留
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并删旧表,但必须人工核对:SHOW CREATE TABLE t1确认字符集、索引、字段顺序是否正确;再用pt-table-checksum校验数据一致性——COUNT(*)不可靠,触发器同步期间可能有极少量延迟

















