MySQL主从一致性检查工具percona-toolkit简介

  • A+
所属分类:Basic

MySQL主从同步的时候,如果当从库因为意外或者其他特殊情况导致宕机,重新启动后可能会产生主从数据不一致的情况发生。因此需要借助pt-table-checksum来进行检查。

一、原理简介

pt-table-checksum运行在主库上,通过show processlist或show slave hosts或DSN方式来确定从库并连接,默认使用crc32算法来进行数据校验,该工具之所以需要把binlog设置为statement格式,是因为该工具能得出主从是否一致所依赖的就是statement基础上同样的SQL语句在主从库上各自的执行结果,主库进行检查后sql语句传给从库,从库执行一遍后,也得到自己的结果,执行语句是:

注: where的条件是根据系统繁忙程度计算出的要执行的范围。

cnt是目前检查的块包括的行数,unsigned是计算出的该块数据的校验值。

如果主库和从库得出的这两个值都是一样的,那数据就是一致的,如果不一样,那就主从不一致,当然,字符集、浮点数之类的问题需要提前规避,以免错判。

工具将主从各自得到的结果处理后放到checksums表中并呈现一些结果在屏幕输出中。

二、安全性保障

pt-table-checksum采用了很多措施来保证检查过程中的安全性,默认参数是可以保障使用安全的,不过参数可以配置,所以需要详细了解参数的功能后再进行更改,否则最好采用默认。

先了解一下工具在执行过程中做了些什么:

主库:

从库:

检查结果:

pt-table-checksum一次只针对一个表,而且会根据表的大小以及当前系统的繁忙程度,计算出一次检查中能包含的数据行数,来尽量避免对线上服务的影响,如果在执行过程中遇到突发的负载增加,还会自动的将检查停下来等待,所以即使面对成千上万的数据库和表时,它也能顺利的进行检查

在检查过程中,工具会随时对主从连接情况进行检查,如果从库延迟太大,主从复制中断,检查会停下来等待;这里需要注意的是主从复制过滤,因为这种情形下,主从数据库中的库表存在情况不一致,检查过程中的执行语句会与当前的主从复制过程冲突导致主从复制进程失败,所以如果有过滤存在,需要指定参数--no-check-replication-filters

在一个块的数据被检查之前,会先执行explain操作,来确定执行该检查的安全性,如果太大不能在指定时间内完成检查的话就会将该块数据跳过,另外,如果主库上整表的数据特别少或干脆是空表,并不会直接将整表当做一个块去检查,而是会再去从库,确定从库中也是有同样少的数据,避免从库表数据太多却被当成一个块执行造成的从库数据阻塞

另外还有一些安全保护设置,在上面的执行流程中已经列出来了,如设置innodb_lock_wait_timeout=1,如果锁等待超过1S,就放弃此次执行

在执行过程中如果遇到任何异常,可随时中断进程,如kill或CTRL-C,不会造成任何影响,后面想从此次中断继续检查时,简单的采用--resume就可以。

三、参数介绍

1. 连接主从库的参数:
--host --socket --user --password --pid --port
2. 确定比较范围的参数
(1) 指定库
--databases / --ignore-databases 要比较的库 / 比较过程中忽略这些库
--databases-regex / --ignore-databases-regex 同上,不过可以用正则匹配
(2) 指定表
--tables / --ignore-tables 要比较的表 / 比较过程中忽略这些表
--tables-regex / --ignore-tables-regex 同上,不过可以用正则匹配
(3) 指定列
--columns / --ignore-columns 要比较的列 / 比较过程中忽略这些列
(4) 直接指定表范围
--where 直接指定表中要比较的范围
(5) 根据引擎选表
--engines / --ignore-engines 比较指定的引擎表 / 比较过程中忽略含有这些引擎的表
3. 指定连接中断后行为的参数
--resume 如果主从一致性检查中途中断的话,可以用这个参数来使工具从上次中断时检查的最后一个表开始继续检查
--retries 如果在检查过程中有非致命性的中断的话,如被kill或者从库延迟等,指定该参数后,工具会自动尝试重连

重点参数:

(1) --[no]check-binlog-format
默认会检查binlog-format,如果不是statment,就会报错退出,想避免该检查可以设置--no-check-binlog-format
(2) --recursion-method
参数有四:processlist/hosts/dsn=DSN/no,默认是processlist,hosts,但最好还是指定一下,建议指定--recursion-method=processlist,no一般不使用
dsn=DSN方法使用时,需要先去库里创建一个表,比如在percona库中建一个dnsn表

建好后插入主从复制信息数据,如:insert into table dsns(dsn) values(h=slave_host,u=repl_user,p=repl_password,P=port );
然后就可以使用DSN方法了:命令为:--recursion-method dsn=D=percona,t=dsns.
(3) --replicate
用来指定存放计算结果的表名, 默认是percona.checksums,工具会默认自动创建库percona和表checksums并将checksum的检查结果输入到这个表中,如果自己用该参数去指定表的话,表结构必须是:

需要注意的是存储引擎设置,如果检查的表是innodb表,就设置innodb引擎,如果检查的表和checksums表的引擎不一致,如分别是myisam和innodb,会引起复制错误:“different error on master and slave.”!!!

其他参数:

5. 其他部分参数详述:
(1) --[no]check-replication-filters
默认在检查到在主从复制过程中有被用..ignore..过滤掉的表,检查会中断并退出,如果想避开这个检查可以设置--no-check-replication-filters
(2) --chunk-index(type: string)
工具默认在分块时会选取最合适的索引来explain确定chunk的大小,但如果你希望用其他索引来执行,可以用该参数来指定,工具会以FORCE INDEX的形式把指定的索引加进去
(3) --chunk-index-columns(type: int)
可以用来指定组合索引中使用前几个列来辅助分块
(4) --chunk-size
直接确定chunk的大小,默认1000行数据,但不建议使用,建议使用--chunk-time代替
(5) --chunk-time
默认是0.5秒,工具会根据当前系统运行繁忙程度计算出在该指定时间内可以处理的数据行数(即chunk),比较灵活
(6) --[no]empty-replicate-table
默认yes,每次检查表之前都去把checksums表中已有的该表信息删掉,以利于后续重新插入新检查信息
(7) --float-precision(type: int)
设置浮点数的四舍五入方式,以避免不同版本间或其他特定情况中,主从间因浮点数四舍五入的方式不同而导致查出不一致,If you specify a value of 2, for example, then the values 1.008 and 1.009 will be rounded to 1.01, and will checksum as equal
(8) --function
计算checksum值时的函数,默认是CRC32,其他还有FNV1A_64, MURMUR_HASH, SHA1, MD5等
(9) --max-lag
默认1S,主从最大延迟,超过这个延迟时间,就会停下来等待从库同步,确定方法是采用Seconds_Behind_Master的值
(10) --progress
指定后可以按设定的参数将执行过程中的运行情况输出到STDERR,如主从延迟时从库的等待,等待时间等,指定时后跟两个参数值,默认是 "time,30",前一个参数有:percentage, time, or iterations;后一个指定百分比,具体时间或者间隔的数目

四、案例演示

1:基础数据

①:主库数据建立:

②:从库增加一条数据

2:演示案例

工具安装:

主库授权:

检查:【主库运行】

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

从库检查:【检查结果保存在从库】

主库打印语句:

主库执行语句:
法1:

法2:

一致性验证:

快速上手:

备注:

(1)在有些情况下,recursion-method如果不设会报错:Diffs cannot be detected because no slaves were found. 其参数有四:processlist/hosts/dsn=DSN/no,用来决定查找slave的方式是show full processlist还是show slave hosts还是命令行直接指定还是压根就不准备找从库,具体见下面参数介绍
(2)主从的端口必须一致,如果不一致就需要用DSN方法进行指定,否则会报找不到从库的错误,如果能连到从库服务器但没有指定端口,默认会寻找3306端口
(3)被检查的主从binlog_format必须为statement,如果不是statement-based,那就添加参数--no-check-binlog-format来避开binlog格式检查
(4)检查结果会输出到默认建立的percona库中的checksums表中,并会输出统计信息到屏幕,diffs列展示主从数据不一致的块的数目,如果都是0,恭喜,数据是一致的

转载于:

1:http://www.cnblogs.com/xiaoyanger/p/5584554.html
2:https://segmentfault.com/a/1190000004309169