首页 > 技术文章 > Mysql一致性效验_pt工具

rxysg 2021-12-14 14:44 原文

一.简介

pt工具可以随机抽取主从的数据进行对比,用于测试主从数据一致性。也可以对不一致数据进行修复。这个工具在主或者从上安装均可

二.原理介绍

它通过在主库执行基于statement的sql语句来生成主库数据块的checksum,把相同的sql语句传递到从库,并在从库上计算相同数据块的checksum,最后,比
较主从库上相同数据块的checksum值,由此判断主从数据是否一致。这种校验是分表进行的,在每个表内部又是分块进行的,而且pt工具本身提供了非常多的限
流选项,因此对线上服务的冲击较小。

pt工具选择智能分析表上的索引,然后把表的数据split成一个个chunk,计算的时候也是以chunk为单位。每一次对chunk进行checksum后,pt工具都会对耗时
进行统计分析,并智能调整下一个chunk的大小,避免chunk太大对线上造成影响,同时也要避免chunk太小而效率低下。

连接到主库:pt工具连接到主库,然后自动发现主库的所有从库。默认采用show full processlist来查找从库,但是这只有在主从实例端口相同的情况下才有效。

内部工作过程:

  1. 连接到主库:pt工具连接到主库,然后自动发现主库的所有从库。默认采用show full processlist来查找从库,但是这只有在主从实例端口相同的情况
    下才有效。
  2. 查找主库或者从库是否有复制过滤规则:这是为了安全而默认检查的选项。你可以关闭这个检查,但是这可能导致checksum的sql语句要么不会同步到从
    库,要么到了从库发现从库没有要被checksum的表,这都会导致从库同步卡库。
  3. 开始获取表,一个个的计算。
  4. 检查表结构,进行数据类型转换等,生成checksum的sql语句。
  5. 根据表上的索引和数据的分布,选择最合适的split表的方法。
  6. 开始checksum表。
  7. 默认在chunk一个表之前,先删除上次这个表相关的计算结果。除非—resume。
  8. 根据explain的结果,判断chunk的size是否超过了你定义的chunk-size的上限。如果超过了,为了不影响线上性能,这个chunk将被忽略。
  9. 把要checksum的行加上for update锁,并计算。
  10. 把计算结果存储到master_crc master_count列中。
  11. 调整下一个chunk的大小。
  12. 等待从库追上主库。如果没有延迟备份的从库在运行,最好检查所有的从库,如果发现延迟最大的从库延迟超过max-lag秒,pt工具在这里将暂停。
  13. 如果发现主库的max-load超过某个阈值,pt工具在这里将暂停。
  14. 继续下一个chunk,直到这个table被chunk完毕。
  15. 等待从库执行完checksum,便于生成汇总的统计结果。每个表汇总并统计一次。
  16. 循环每个表,直到结束。

三.选项

使用选项:
--[no]check-replication-filter 是否检查复制过滤规则,如果主库和从库都没有过滤规则,可以选择不检查过滤规则
--[no]check-binlog-format pt需要主库使用STATEMENT格式的binlog, 如果binlog是MIXED格式,最好指定--nocheck-binlog-format
--check-slave-tables 检查是否所有从库都有被检查的表和列,会消耗一定的时间

安全选项:
--chunk-size-limit 将表分成chunk的最大大小,超过这个值的chunk则跳过
--check-slave-lag 指定只检查某个从库的延迟,不指定则检查所有从库的延迟
--max-lag 最大延迟,如果从库与主库之间的延迟超过这个值, pt将会等待从库与主库同步
--max-load 最大负载,如果主库上的负载超过这个值, pt将会等待主库的负载降低

限制选项:
--replicate 指定检查的结果存放位置,默认存放在percona.checksums表中,可以手动指定其他表
--databases 只检查某些库
--tables 只检查某些表
这些过滤选项在修复不一致数据后,检查修复效果很有用。

过滤选项:
--resume 上次检查因为某种原因中断,下次接着执行,不用从头开始
--chunk-time 检查每个chunk的用时,默认是0.5s

四.环境

系统:centos-7.3 2台
mysql版本:5.7
软件版本:3.0.3

五.部署

1.安装依赖
yum install perl-IO-Socket-SSL perl-DBD-MySQL perl-Time-HiRes perl perl-DBI perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker perl-Digest-MD5

2.安装源码包
wget https://www.percona.com/downloads/percona-toolkit/3.0.3/binary/redhat/6/x86_64/percona-toolkit-3.0.3-1.el6.x86_64.rpm
yum localinstall percona-toolkit-3.0.3-1.el6.x86_64.rpm

3.在master和slave创建账号:
mysql>GRANT SELECT,PROCESS,SUPER,REPLICATION SLAVE,CREATE,DELETE,INSERT,UPDATE ON *.* TO 'check'@'%' identified by '123456';
mysql>flush privileges;
说明:指定host为安装软件的机器ip

4.执行:
pt-table-checksum --nocheck-replication-filters --no-check-binlog-format --replicate=cnt.checksums --databases=cnt --tables=ldb_alipay_order h=1.1.1.1,u=check,p=123456,P=3306

参数说明:
--no-check-replication-filters 表示不需要检查 Master 配置里是否指定了 Filter。 默认会检查,如果配置了 Filter,如 replicate_do_db,replicate-wild-ignore-table,binlog_ignore_db 等,在从库checksum就与遇到表不存在而报错退出,所以官方默认是yes(--check-replication-filters)但我们实际在检测中时指定--databases=,所以就不存在这个问题,干脆不检测。

--no-check-binlog-format 不对binlog的格式进行检查

--replicate-check-only 只显示主从不一致部分,此参数不会生成新的checksums数据,只会根据checksums表已经有的数据来显示

--databases=,-d:要检查的数据库,逗号分隔。 --databases-regex 正则匹配要检测的数据库,--ignore-databases[-regex]忽略检查的库。Filter选项。

--tables=,-t:要检查的表,逗号分隔。如果要检查的表分布在不同的db中,可以用--tables=dbname1.table1,dbnamd2.table2的形式。
同理有--tables-regex,--ignore-tables,--ignore-tables-regex。--replicate指定的checksum表始终会被过滤。
file

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

提示错误:
问题一:
Waiting for the --replicate table to replicate to localhost.localdomain...
问题出在percona.checksums 表在从库不存在,根本原因是没有从主库同步过来,所以看一下从库是否延迟严重。

问题二:
Diffs cannot be detected because no slaves were found. Please read the --recursion-method documentation for information.
上面的提示信息很清楚,因为找不到从,所以执行失败。用参数--recursion-method 可以指定模式解决.

测试:
主不写,从写入1条数据,再运行效验工具,可以看到错误

推荐阅读