MySQL主从数据一致性检查

背景

mysql设置了主从同步,通过show slave status查看,Slave_IO_RunningSlave_SQL_Running都是yes,但实际发现有几张表没有同步成功。

原因

Slave_IO_Running: YesSlave_SQL_Running: Yes 只能证明通信管道是正常的,即:
IO线程能正常从主库拉取 Binlog。
SQL线程正在正常执行 Binlog 中的语句,没有因为报错而停止。

但这并不代表主从数据是一致的。出现这种“状态正常但数据不一致”的情况。

如何检查

使用专业工具 Percona Toolkit 中的 pt-table-checksum
它会在 Slave 上计算校验值,你可以看到哪些具体的表 DIFF 不为 0。

安装依赖

CentOS / RHEL / AlmaLinux / Rocky Linux:

# 安装基础 Perl DBI 模块
sudo yum install -y perl-DBI

# 安装 MySQL 驱动模块 (必须安装,否则会报 DBD::mysql 缺失)
sudo yum install -y perl-DBD-MySQL

# 如果报错提示缺少 Time::HiRes
sudo yum install -y perl-Time-HiRes

Ubuntu / Debian:

# 更新索引
sudo apt-get update

# 安装基础 Perl DBI 和 MySQL 驱动模块
sudo apt-get install -y libdbi-perl libdbd-mysql-perl

# 如果报错提示缺少 Time::HiRes
sudo apt-get install -y libtime-hires-perl

验证依赖是否安装成功

执行以下两条命令,如果没有报错,说明安装成功:

perl -MDBI -e 'print "DBI OK\n"'
perl -MDBD::mysql -e 'print "MySQL Driver OK\n"'

安装 Percona Toolkit

# 下载最新版本
wget https://downloads.percona.com/downloads/percona-toolkit/3.5.5/binary/tarball/percona-toolkit-3.5.5_x86_64.tar.gz

# 解压
tar -xzf percona-toolkit-3.5.5_x86_64.tar.gz

# 移动到系统路径
sudo cp percona-toolkit-3.5.5/bin/* /usr/local/bin/

# 验证
pt-table-checksum --version

创建检测用的数据库用户(在主库执行)

-- 创建专用用户
CREATE USER 'checksum'@'%' IDENTIFIED BY 'your_password';

-- 授权(需要较高权限)
GRANT SELECT, PROCESS, SUPER, REPLICATION SLAVE ON *.* TO 'checksum'@'%';
GRANT ALL PRIVILEGES ON percona.* TO 'checksum'@'%';

-- 刷新权限
FLUSH PRIVILEGES;

注意: 该用户需要在主库和从库都能登录,且权限一致。

开始检测

pt-table-checksum \
  --host=[数据库地址] \
  --user=[数据库账号] \
  --password=[数据库密码] \
  --replicate=percona.checksums \
  --recursion-method hosts \
  --no-check-binlog-format
  --databases=[数据库名]  # 明确指定数据库,去掉这行则检查所有的数据库

结果解读

输出示例

            TS ERRORS  DIFFS     ROWS  DIFF_ROWS  CHUNKS SKIPPED    TIME TABLE
12-20T10:30:15      0      0    15000          0       3       0   1.234 your_db.table1
12-20T10:30:18      0      1    23000        150       5       0   2.456 your_db.table2
12-20T10:30:20      0      0     5000          0       1       0   0.789 your_db.table3

字段含义:

  • TS: 检测时间戳
  • ERRORS: 执行错误数(如权限不足)
  • DIFFS: 不一致的 chunk 数量(关键指标)
  • ROWS: 总行数
  • DIFF_ROWS: 不一致的行数(关键指标)
  • CHUNKS: 分块数
  • SKIPPED: 跳过的块数
  • TABLE: 表名
    如果 DIFFS > 0,说明该表主从数据不一致!

查看详细的不一致记录

-- 在主库查询检测结果表
USE percona;

-- 查看所有不一致的表
SELECT db, tbl, SUM(this_cnt) AS master_cnt, SUM(master_cnt) AS slave_cnt
FROM checksums
WHERE master_cnt <> this_cnt OR master_crc <> this_crc
GROUP BY db, tbl;

-- 查看具体哪个从库不一致
SELECT * 
FROM checksums 
WHERE master_cnt <> this_cnt OR master_crc <> this_crc;

发表评论

邮箱地址不会被公开。 必填项已用*标注