MySQL从库读取数据不一致是主从复制架构中常见的故障场景,通常表现为从库查询到的数据和主库存在记录缺失、字段值不同等差异,会直接影响业务的正常逻辑。这种问题多发生在主从复制延迟过高、主库执行了非确定性函数、从库被意外写入数据等场景下,需要第一时间进行全量或增量的一致性校验,定位差异范围后再做修复。

主从数据不一致的常见原因
了解不一致的原因有助于更有针对性地做校验和修复,常见诱因主要有以下几类:
- 主从复制延迟:从库SQL线程回放主库binlog的速度跟不上主库写入速度,导致短时间内的数据查询存在差异,这种差异通常是暂时的,但如果延迟持续扩大就会成为永久差异。
- 非确定性操作:主库执行了UUID()、NOW()、RAND()这类非确定性函数,或者使用了STATEMENT格式的binlog,导致从库回放后的结果和主库不一致。
- 从库意外写入:从库被配置了可写权限,业务或者运维人员直接在从库执行了插入、更新、删除操作,破坏了和主库的数据同步关系。
- 主从服务器配置差异:主从的字符集、时区、sql_mode等参数不一致,导致同一条SQL执行后产生不同的结果。
使用pt-table-checksum执行强制一致性校验
pt-table-checksum是Percona Toolkit工具集里专门用于校验MySQL主从数据一致性的工具,它会在主库上执行校验逻辑,自动对比主库和从库的数据差异,输出清晰的校验结果,是业内最常用的主从数据校验方案。
工具安装与前置准备
首先需要安装Percona Toolkit,以CentOS系统为例,安装命令如下:
# 安装Percona源 yum install -y https://repo.percona.com/yum/percona-release-latest.noarch.rpm # 安装Percona Toolkit yum install -y percona-toolkit
校验前需要满足几个前置条件:
- 主库和从库的网络互通,且主库的binlog格式建议设置为ROW格式,避免STATEMENT格式带来的校验偏差。
- 主库上需要存在一个有全库读取权限、并且有校验表写入权限的账号,示例账号创建语句如下:
-- 创建校验专用账号,替换为实际的密码和从库IP段 CREATE USER 'checksum_user'@'192.168.0.%' IDENTIFIED BY 'your_password'; GRANT SELECT, PROCESS, SUPER, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'checksum_user'@'192.168.0.%'; GRANT ALL PRIVILEGES ON percona.* TO 'checksum_user'@'192.168.0.%'; FLUSH PRIVILEGES;
执行全量一致性校验
在主库所在的服务器上执行以下命令,对所有业务库执行强制一致性校验:
pt-table-checksum --host=127.0.0.1 --port=3306 --user=checksum_user --password=your_password --databases=db1,db2 # 替换为实际需要校验的数据库名,不指定则校验所有库 --recursion-method=processlist # 通过processlist自动发现从库 --no-check-binlog-format # 如果确认binlog格式没问题可以去掉该参数 --replicate=percona.checksums # 校验结果存储的表
命令执行完成后,工具会把每个表的校验结果写入到percona.checksums表中,同时会在终端输出汇总的校验信息。如果输出中DIFFS列的数值大于0,说明对应的表存在主从数据差异。
查看具体差异信息
可以直接在主库上查询percona.checksums表,获取存在数据差异的具体表信息:
-- 查询存在数据差异的表
SELECT
db,
tbl,
SUM(this_cnt) AS master_cnt,
SUM(this_crc) AS master_crc,
SUM(master_cnt) AS total_master_cnt,
SUM(master_crc) AS total_master_crc,
SUM(slave_cnt) AS slave_cnt,
SUM(slave_crc) AS slave_crc,
COUNT(*) AS diff_tables
FROM percona.checksums
WHERE master_cnt <> slave_cnt OR master_crc <> slave_crc
GROUP BY db, tbl;
校验后的差异修复方法
定位到差异表之后,可以使用pt-table-sync工具来修复主从数据差异,该工具会生成对应的修复SQL,在从库上执行后就可以让数据和主库保持一致。
生成修复语句的命令如下,执行前建议先开启从库的只读模式,避免修复过程中有新的写入操作:
pt-table-sync --execute --host=127.0.0.1 --port=3306 --user=checksum_user --password=your_password --databases=db1 # 替换为存在差异的数据库名 --tables=tbl1,tbl2 # 替换为存在差异的表名 --sync-to-master 192.168.0.2:3306 # 替换为从库的实际地址和端口
如果不确定修复语句是否正确,可以先把--execute参数替换为--print,工具只会输出要执行的SQL,不会实际执行,确认无误后再换成--execute执行修复。
日常预防主从不一致的建议
除了出现问题后做校验修复,日常运维中也可以通过以下方式减少主从不一致的概率:
- 统一主从服务器的核心配置,包括字符集、时区、sql_mode、binlog格式等参数。
- 从库配置read_only=1和super_read_only=1,避免非预期的业务写入。
- 定期执行pt-table-checksum校验,建议每周至少做一次全量校验,重要业务可以每天执行。
- 监控主从复制状态,及时告警并处理复制延迟、复制中断等问题。
MySQL主从复制数据一致性pt-table-checksum修改时间:2026-06-21 04:21:36