pt-table-checksum连接主库失败的常见原因:账号缺少replication client、process、select或insert/update权限;主库bind_address未设为0.0.0.0或内网ip;防火墙未放行3306端口;require_secure_transport=on时未加--ssl参数。

pt-table-checksum 连接主库失败的常见原因
直接执行 pt-table-checksum 报错 Access denied for user 或 Can't connect to MySQL server,基本是权限或网络配置没到位。它必须用有 REPLICATION CLIENT、PROCESS、SELECT 和 INSERT/UPDATE/DELETE(对 percona.checksums 表)权限的账号连接主库,且该账号需能从运行 pt 的机器访问主库 —— 不是只看本地登录权限。
- 主库
bind_address不能设为127.0.0.1,得是0.0.0.0或具体内网 IP - 防火墙要放行主库 MySQL 端口(默认 3306)到 pt 执行机
- 账号授权语句必须包含
GRANT REPLICATION CLIENT, PROCESS, SELECT ON *.* TO 'pt_user'@'pt_host';,别漏PROCESS,否则查不到从库状态 - 如果主库开了
require_secure_transport=ON,pt 命令得加--ssl参数,否则握手失败
为什么 checksum 结果里从库显示 DIFFS=1 却查不出不一致的表?
pt-table-checksum 默认只校验主库上当前有写入的表(通过 SHOW MASTER STATUS 的 position 判断),如果某张表在 checksum 执行期间完全没被 DML 触发 binlog 更新,它的校验结果就不会同步到从库的 percona.checksums 表里 —— 导致从库查不到该表记录,DIFFS 就会误报为 1。
- 加
--replicate-check-only参数可跳过重新计算,只比对已存在的 checksum 记录 - 更稳妥的做法是加
--check-interval=1(秒)并配合--max-load,让工具持续观察一段时间内的变更,覆盖静默表 - 注意
--databases范围要和实际业务库一致,漏写库名会导致对应库下所有表不参与校验
如何定位具体哪一行数据不一致?
pt-table-checksum 只告诉你“有差异”,不告诉你“差在哪”。真要定位到行级,得靠 pt-table-sync 配合 --print 模式生成修复 SQL,再人工核对:
pt-table-sync --replicate percona.checksums --sync-to-master --print h=slave_host,u=pt_user,p=xxx
这条命令不会真正执行同步,只输出类似 UPDATE db.tbl SET c1='x' WHERE id=123 /* PADDING */ 的语句。关键点在于:
- 必须确保从库的
percona.checksums表已由pt-table-checksum写入最新结果,否则pt-table-sync无据可依 -
--sync-to-master表示以主库为基准修复从库,反向修复要用--reverse - 如果表没主键或唯一键,
pt-table-sync会拒绝操作,报错No unique index found—— 这时候只能手动导出两库数据用diff对比
高并发写入时执行 checksum 导致主库延迟飙升怎么办?
默认情况下,pt-table-checksum 会按 chunk 切分大表逐块计算 CRC32,但若 chunk 太大或并发太高,单次查询可能锁住热点行数秒,拖慢主库事务。这不是 bug,是设计使然 —— 它需要一致性快照。
- 用
--chunk-size控制每块行数(如--chunk-size=1000),避免单次扫描太久 - 加
--max-load=Threads_running=25,当主库Threads_running > 25时自动暂停,缓解压力 - 避开业务高峰;或者用
--recursion-method=none+ 手动指定从库地址,避免工具自己探测从库时额外开销 - 如果主库用了 MGR 或 Group Replication,务必加
--set-vars="innodb_lock_wait_timeout=3",防止 checksum 事务被长事务阻塞
checksum 本身不改数据,但它依赖主库的实时状态,任何影响主库响应的因素都会放大它的副作用。最常被忽略的是从库的 relay_log_space_limit 设置过小,导致 checksum 期间 relay log 写满、SQL 线程卡住,看起来像主从延迟暴增 —— 其实是中继日志满了。











