pt-table-checksum连不上从库主因是权限不足或连接参数错误,需确保从库账号具备SELECT、PROCESS、SUPER、REPLICATION SLAVE权限并能建表,且显式指定从库DSN而非依赖默认继承。

pt-table-checksum 连不上从库或报错 "Access denied"
常见原因是权限不足或连接参数写错。这个工具需要在主库执行,但会把校验 SQL 透传到从库执行,所以从库连接账户必须有 SELECT、PROCESS、SUPER、REPLICATION SLAVE 权限,还要能建表(因为默认会在指定库下创建 checksums 表)。
实操建议:
- 在从库上显式执行
GRANT SELECT, PROCESS, SUPER, REPLICATION SLAVE ON *.* TO 'pt_user'@'%' IDENTIFIED BY 'xxx'; FLUSH PRIVILEGES;,别只给主库授。 - 检查
--recursion-method参数:如果设为processlist(默认),它会去从库查SHOW PROCESSLIST找复制线程,若从库禁用了该命令或账户没权限,就会失败;可临时改用dsn=t指定从库列表,绕过自动发现。 - 确保主库的
binlog_format是STATEMENT——pt-table-checksum默认依赖该格式生成可复制的校验语句;若你强制用ROW,得加--no-check-binlog-format,但风险自担。
校验时卡住或长时间无输出
不是程序挂了,大概率是碰到大表、慢查询或从库延迟太高。工具默认会等从库追上当前校验 chunk 的位点才继续,避免因复制延迟导致误判不一致。
实操建议:
- 加
--max-lag=30s(单位秒),超过阈值就暂停校验,等从库追上来再继续;别用默认的无限等待。 - 避开业务高峰,用
--check-interval=1m控制每 chunk 后休眠时间,减轻从库压力。 - 确认目标表有主键或非空唯一键 ——
pt-table-checksum依赖它分块;没有的话会跳过或报错Cannot chunk table without a primary key or unique not null index。 - 如果表特别大(比如 >50GB),先用
--chunk-size=1000缩小单次处理行数,避免锁表太久或内存溢出。
checksums 表里显示 chunk 不一致,但实际数据看起来一样
这通常不是误报,而是校验逻辑和数据状态存在“时间差”。比如校验过程中主库正在写入某 chunk 对应的数据,而从库还没同步完,就会导致 CRC 值不同。
实操建议:
- 不要立刻修复,先运行
pt-heartbeat确认当前主从延迟是否归零;延迟 >0 时所有不一致结果都不可信。 - 检查是否用了
NOW()、UUID()、RAND()等非确定性函数——这些在STATEMENT格式 binlog 下必然导致主从计算结果不同。 - 核对主从的
sql_mode是否一致,比如一个开了STRICT_TRANS_TABLES,另一个没开,字段截断行为不同,CRC 自然不同。 - 直接连从库查
SELECT this_crc, master_crc FROM test.checksums WHERE db='xxx' AND tbl='yyy',看哪些 chunk 的值真不相等;别只看is_bad字段,它可能被旧数据污染。
怎么安全地修复不一致数据
pt-table-sync 不是拿来直接执行的,它是生成 SQL 的“预演工具”。线上环境必须走 --print + 人工审核 + 从库执行三步流程。
实操建议:
- 先用
pt-table-sync --replicate=test.checksums --sync-to-master h=从库IP,u=用户,p=密码 --print > fix.sql导出 SQL;注意这里h=指的是从库地址,不是主库。 - 打开
fix.sql,确认里面只有REPLACE或DELETE/INSERT,没有意外的DROP TABLE或跨库操作;尤其警惕带WHERE条件的语句是否覆盖了不该动的行。 - 在从库上执行前,务必
SET sql_log_bin=0;,否则修复语句又会写进 binlog,被主库再次应用,形成循环。 - 修复后别急着删
checksums表,再跑一遍pt-table-checksum,确认cnt_diff和sum_crc都为 0 —— 这才是闭环。
真正容易被忽略的是:校验不是一次性动作。主从架构下,一次通过不代表永远一致;网络抖动、人为误操作、配置漂移都可能随时引入偏差。建议把 pt-table-checksum 加入定时任务,配合告警(比如监控 cnt_diff > 0 的行数),而不是等业务报错才想起查。











