pt-online-schema-change通过影子表+触发器机制实现在线切换引擎,避免原生ALTER TABLE的锁表问题;其核心流程包括创建InnoDB影子表、建立同步触发器、分批拷贝数据、原子切换表名,并需--execute显式执行及满足主键、权限等前提条件。

直接执行 ENGINE=InnoDB 会锁表,必须用 pt-online-schema-change
MySQL 原生 ALTER TABLE ... ENGINE=InnoDB 在 5.7 及更早版本中默认走 copy 算法,全程锁表;8.0 虽支持 ALGORITHM=INPLACE,但仅对部分引擎转换有效(比如 MyISAM → InnoDB 不支持 inplace),且仍需元数据锁阻塞 DDL。所以只要不是“纯内存表”或极小表,就别指望原生命令能在线切引擎。必须用 pt-online-schema-change。
pt-online-schema-change 切引擎的命令写法和关键参数
核心命令结构固定:pt-online-schema-change --alter "ENGINE=InnoDB" D=your_db,t=your_table --execute。注意以下几点:
-
--alter中的语句必须是单条合法 ALTER 子句,不能带逗号、不能多操作(比如不能同时改引擎+加索引) - 必须显式加
--execute,否则只做预检不真正执行 - 推荐加上
--chunk-size=1000(控制每次拷贝行数)和--max-load="Threads_running=25"(防主库过载) - 如果表有外键,得加
--alter-foreign-keys-method=auto,否则工具直接拒绝运行
为什么切引擎也要建触发器?它同步什么?
因为引擎切换本质是重建表结构 + 迁移数据,而 pt-online-schema-change 的影子表在创建时就指定了新引擎(如 CREATE TABLE _t_new ENGINE=InnoDB ...)。触发器不是同步“引擎”,而是同步“数据变更”——在原表(可能是 MyISAM)上发生的 INSERT/UPDATE/DELETE,会通过触发器实时写入影子表(InnoDB)。这保证了迁移过程中业务写入不丢、不乱。特别注意:MyISAM 表本身不支持事务,但触发器执行是在当前会话上下文中,所以影子表的写入仍受 InnoDB 事务保护。
容易被忽略的三个坑
一是权限:用户必须有 TRIGGER 权限,否则建触发器失败,整个流程卡在第二步;
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
二是主键:MyISAM 表允许无主键,但 pt-online-schema-change 强制要求原表有主键或唯一非空索引,否则报错 Cannot chunk the table because no suitable index was found;
三是复制延迟:如果该表是主从架构中的主表,且从库延迟超过 --max-lag=30s(默认值),工具会暂停拷贝,等从库追平才继续——这点常被误认为“卡住”,其实是保护机制。










