使用Percona-Toolkit为MySQL表字段加索引时的复制同步问题
解决pt-online-schema-change索引修改未同步到从库的问题
嘿,咱们来搞定你碰到的这个麻烦:在主库host1用pt-online-schema-change成功加了索引,结果从库host2、host3没同步上,还不敢直接在从库跑命令怕搞坏复制——这确实是个容易踩坑的点,咱们一步步来解决。
一、先排查主从复制的健康状态
首先得确认主从复制是不是正常跑着,毕竟如果复制本身断了或者延迟太高,主库的修改肯定传不到从库。你可以在host2和host3上执行这条命令检查:
SHOW SLAVE STATUS\G
重点盯着这几个关键字段:
Slave_IO_Running和Slave_SQL_Running:这俩必须都是Yes,要是有一个是No,说明复制已经中断了,得先把这个问题解决掉。Seconds_Behind_Master:如果数值很大,说明复制有严重延迟,得等从库追上主库之后,再看索引有没有同步过来。Last_Error:如果这里有错误信息,那就是复制中断的根源,比如主从表结构不一致、主键冲突之类的,得先把这个错误排除。
二、为什么pt-osc的修改没同步到从库?
pt-online-schema-change的工作逻辑是:先建一个和原表结构一致的临时表,在临时表上做结构修改(比如加索引),然后把原表的数据分批迁移到临时表,最后替换原表。整个过程的所有操作都会写入主库的binlog,正常情况下会通过复制自动同步到从库。如果没同步,大概率是复制环节出了问题,比如:
- 主库的binlog没传到从库(IO线程挂了)
- 从库的SQL线程执行binlog时报错停了
- 你的复制配置里加了
replicate-ignore-table,刚好忽略了这个表的操作
三、绝对不能直接在从库执行pt-osc!
直接在从库跑pt-online-schema-change是典型的作死操作——从库是跟着主库同步的,你在从库改表结构,会导致主从表结构不一致,后续复制肯定会报错,甚至直接断了。正确的做法分两种情况:
情况1:复制正常,只是延迟没追上
如果排查后发现复制是正常的,只是Seconds_Behind_Master数值比较大,那耐心等从库追上主库就行,索引会自动同步过来。
情况2:复制中断/索引确实没同步
如果复制已经修复,但索引还是没出现在从库,或者复制中断导致同步失败,可以这么操作:
- 先停掉从库的复制:
STOP SLAVE;
- 如果从库是只读状态,先临时关闭只读(操作完再改回去):
SET GLOBAL read_only = 0;
- 在从库手动执行加索引的SQL(如果表数据不大,这个操作很快;如果数据量很大,也可以用pt-osc,但要注意从库此时已经脱离主库,操作完再同步):
ALTER TABLE customer.test_percona_restructure ADD INDEX server (server) USING BTREE;
- 恢复只读状态(如果之前开了的话):
SET GLOBAL read_only = 1;
- 启动复制:
START SLAVE;
- 再次执行
SHOW SLAVE STATUS\G检查复制状态,确保Slave_IO_Running和Slave_SQL_Running都是Yes,没有新的错误。
四、预防下次踩坑的小技巧
- 每次执行pt-osc之前,先检查所有从库的复制状态,确保都正常。
- 可以给pt-osc加
--check-slave-lag参数,让工具自动监控从库延迟,延迟超过阈值(默认1秒)就暂停数据迁移,等从库追上再继续,比如:
pt-online-schema-change --alter "ADD INDEX server (server) USING BTREE" --check-slave-lag h=host2,h=host3 D=customer,t=test_percona_restructure,u=user,p=password h=host1
这样能最大程度保证主从数据的一致性,避免同步不上的问题。
内容的提问来源于stack exchange,提问作者sudodashell
相关产品推荐
相关产品推荐

