MySQL主从一致性的快速校验

最近测试环境的MySQL出现了偶发主从同步失败的现象。主从同步失败的问题很快的得到了解决。但我对于测试环境的数据库主从数据是否完全一致产生了怀疑,有怀疑就得有验证,得找个法子验证一下主从数据是否一致。手工检查也可以做,太耗时间,由此便引入了我本次所要介绍的工具pt-table-checksum

原理介绍

pt-table-checksum的工作原理很简单,通过在主库和从库对表进行一致性的checksum计算,如果主从库的某张表(结构或者数据)不一致,那么checksum结果值就不一样,通过对比主库和从库checksum的值就可以很容易的知道主从是否数据一致了(checksum结果见下文示例)。pt-table-checksum同一时间只会对一张表进行checksum计算,所以它不会消耗过多的数据库资源。无论需要检查的MySQL数据库有多大,我们都无需担心。知道了工作原理,其他的就好办了。接下来我们来实际测试一下,看一看这个工具是如何能够方便的帮我们检查主从的不一致。

一个典型的checksum计算结果如下所示:

mysql> select * from checksums limit 1 \G;
*************************** 1. row ***************************
            db: cmdb
           tbl: t_cmdb_tb_1
         chunk: 1
    chunk_time: 0.00604
   chunk_index: NULL
lower_boundary: NULL
upper_boundary: NULL
      this_crc: ef1e7532 --当前库表计算值
      this_cnt: 107 --当前表记录数
    master_crc: ef1e7532  --主库表计算值
    master_cnt: 107 --主库表记录数
            ts: 2020-12-18 11:06:37

实操部分

1、安装

pt-table-checksum工具存在于percona-toolkit工具包内。基于不同的操作系统下载对应的包进行安装即可,安装过程在此省略。需要注意的一点是percona-toolkit的安装并不限制于主库或是从库,只需要安装在某台能同时访问主库和从库的机器中即可。在笔者的测试环境中,该工具在主库所在的服务器上安装。工具包可以从以下链接找到:

https://www.percona.com/downloads/percona-toolkit/LATEST/

2、基础准备

在使用pt-table-checksum工具之前所需要做的准备工作主要包含以下2步。

1)创建数据库账户

在master和slave上创建统一的账号,并进行必要权限的授权,可参考以下语句:

mysql> grant select,process,super,replication slave,create,delete,insert,update on *.* to 'ms_check_user'@'%' identified by '123456';
mysql> grant all privileges on percona.* to 'ms_check_user'@'%';
mysql> flush privileges;
2)创建用户和表

pt-table_checksum会在主库上自动创建percona数据库以及checksums表,但如果从库设置的同步方式是指定数据库才同步(基于replicate-do-db)的话,那么对应的percona库和checksums表就不会在从库自动创建。在笔者的测试环境中,从库同步的数据库是通过replicate-do-db指定的,因此为了避免出现问题,手动在从库上创建库和表。创建库和表可参考以下语句:

mysql> create database percona;
mysql> use percona;
mysql> CREATE TABLE `checksums` (
    ->   `db` char(64) NOT NULL,
    ->   `tbl` char(64) NOT NULL,
    ->   `chunk` int(11) NOT NULL,
    ->   `chunk_time` float DEFAULT NULL,
    ->   `chunk_index` varchar(200) DEFAULT NULL,
    ->   `lower_boundary` text,
    ->   `upper_boundary` text,
    ->   `this_crc` char(40) NOT NULL,
    ->   `this_cnt` int(11) NOT NULL,
    ->   `master_crc` char(40) DEFAULT NULL,
    ->   `master_cnt` int(11) DEFAULT NULL,
    ->   `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    ->   PRIMARY KEY (`db`,`tbl`,`chunk`),
    ->   KEY `ts_db_tbl` (`ts`,`db`,`tbl`)
    -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

3、测试验证

我们可以通过以下命令在MySQL主库所在服务器上进行测试,以确认CMDB数据库在主从双边是否一致。

pt-table-checksum --no-check-binlog-format --nocheck-replication-filters --databases cmdb -h127.0.0.1 -u'ms_check_user' -p'123456'

该命令中包含的几个可选参数解释如下:
--no-check-binlog-format:检查复制的binlog模式,如果binlog模式是ROW,则会报错;
--nocheck-replication-filters:不检查复制过滤器;
--databases:要进行主从检查的数据库,多个库以逗号分隔;
-h:服务器地址;
-u:账户;
-p:密码;

pt-table-checksum还有许多可选的参数,在此就不做一一介绍了,可以查看以下链接:

https://www.percona.com/doc/percona-toolkit/1.0/pt-table-checksum.html

该命令执行完毕后,我们可以看到类似如下输出。

Checking if all tables can be checksummed ...
Starting checksum ...
            TS ERRORS  DIFFS     ROWS  DIFF_ROWS  CHUNKS SKIPPED   TIME  TABLE
12-18T11:06:37      0      0      107          0       1       0   0.040 cmdb.t_cmdb_tb_1
12-18T11:06:37      0      0       65          0       1       0   0.055 cmdb.t_cmdb_tb_2
12-18T11:06:37      0      0       67          0       1       0   0.052 cmdb.t_cmdb_tb_3
12-18T11:06:37      0      0       83          0       1       0   0.041 cmdb.t_cmdb_tb_4
12-18T11:06:38      0      0        4          0       1       0   0.048 cmdb.t_cmdb_tb_5
12-18T11:06:38      0      0        2          0       1       0   0.042 cmdb.t_cmdb_tb_6

对于该检查输出结果的各项字段解释如下:

TS:完成检查的时间;
ERRORS:检查时候发生错误和警告的数量;
DIFFS:0表示一致,1表示不一致。当指定–no-replicate-check时,会一直为0,当指定–replicate-check-only会显示不同的信息;
ROWS:表的行数;
DIFF_ROWS:不一致的行数;
CHUNKS:被划分到表中的块的数目;
SKIPPED:由于错误或警告或过大,则跳过块的数目;
TIME:执行的时间;
TABLE:被检查的表名;

我们可以看出,对于MySQL中CMDB库的各表检查结果确认主从并未出现任何不一致(所有表的ERRORS和DIFFS都为0)。按照这个方式,我们可以依次对主从涉及到的所有重要数据库进行主从一致性检查。

至此,我们介绍了如何通过pt-table-checksum来实现对MySQL主从的一致性检查。如果检查发现已经存在了数据或结构的不一致,又该如何处理呢?我们可以通过同一软件包内的pt-table-sync工具来实现主从不一致的修复,修复操作如何进行请见下篇文章分解。

你可能感兴趣的:(MySQL主从一致性的快速校验)