pt-online-schema-change能不锁表是因为采用影子表+触发器+增量同步机制,绕过ALTER TABLE的全表独占锁;原表持续可读写,变更由触发器实时捕获并应用到新表,数据分chunk拷贝且每chunk加锁极短。

pt-online-schema-change 为什么能不锁表
它不是魔法,本质是用“影子表 + 触发器 + 增量同步”绕过 ALTER TABLE 的全表独占锁。原表持续可读写,所有变更通过触发器实时捕获并应用到新表;数据分 chunk 拷贝,每个 chunk 加锁时间极短,业务几乎无感。
但注意:它要求主键或唯一非空索引存在,否则无法安全分片;且对高并发写入场景,触发器本身会带来额外开销,可能拖慢写性能。
执行前必须检查的 4 个前提条件
-
pt-online-schema-change需要 MySQL 用户有SELECT、INSERT、UPDATE、DELETE、DROP、CREATE、ALTER、INDEX、TRIGGER权限 —— 少一个都会在中途报错Access denied - 目标表不能有外键(
FOREIGN KEY),否则工具直接退出;如有,得先DROP FOREIGN KEY,改完再加回 - 确保磁盘剩余空间 ≥ 原表大小 × 2(影子表 + binlog 日志增长);
df -h /var/lib/mysql得亲眼确认 - 从库延迟必须
Seconds_Behind_Master: 0,否则主从切换或后续 DDL 同步会出乱子
最常用命令参数怎么配才稳妥
别一上来就跑默认参数。线上表动辄千万行,不控速等于自找雪崩:
- 用
--chunk-size=1000控制每次搬运行数(默认 1000,大表可调小到 500) - 加
--max-load="Threads_running=25",当SHOW STATUS LIKE 'Threads_running'超过 25 就暂停拷贝,避免压垮实例 - 强制指定主键字段:
--alter "ADD COLUMN status TINYINT DEFAULT 0" --primary-key=id,尤其当表有多个唯一索引时,工具可能选错 - 务必加
--dry-run和--print先看它打算建什么表、挂什么触发器,别跳过这步
执行中遇到 ERROR 1105 怎么快速定位
常见报错 ERROR 1105 (HY000): Cannot execute statement: binlog format is not supported,根本原因是 MySQL 的 binlog_format 设成了 STATEMENT。
pt-osc 内部依赖行级复制语义,必须是 ROW 或 MIXED:
- 临时改:执行
SET SESSION binlog_format = ROW(仅当前会话生效) - 永久改:在
my.cnf中写binlog_format = ROW,并重启 mysqld(推荐) - 验证:连上后查
SELECT @@binlog_format,输出必须是ROW
这个点很多人卡住半天,其实就一行配置的事 —— 但不查 @@binlog_format,光看报错根本猜不到根源。


















