最近测试环境的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工具来实现主从不一致的修复,修复操作如何进行请见下篇文章分解。