[关闭]
@gy-ban 2017-01-01T12:28:54.000000Z 字数 2264 阅读 491

pt-table-checksum--mysql数据校验工具

mysql


简介

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

checksum计算原理

1. 单行数据checksum值的计算
pt工具先检查表的结构,并获取每一列的数据类型,把所有数据类型都转化为字符串,然后用concat_ws()函数进行连接,由此计算出该行的checksum值。checksum默认采用crc32,你可以自己定义效率更高的udf。

2. 数据块checksum值的计算
如果一行一行的计算checksum再去和从库比较,那么效率会非常低下。pt工具选择智能分析表上的索引,然后把表的数据split成一个个chunk,计算的时候也是以chunk为单位。因此引入了聚合函数BIT_XOR()。它的功能可以理解为把这个chunk内的所有行的数据拼接起来,再计算crc32的值,就得到这个chunk的checksum值。sql语句如下:

这其中还有count(*),用来计算chunk包含的行数。每一次对chunk进行checksum后,pt工具都会对耗时进行统计分析,并智能调整下一个chunk的大小,避免chunk太大对线上造成影响,同时也要避免chunk太小而效率低下。

3. 一致性如何保证
当pt工具在计算主库上某chunk的checksum时,主库可能还在更新,同时从库可能延迟使得relay-log中还有与这个chunk数据相关的更新,那该怎么保证主库与从库计算的是"同一份"数据?答案是加for update当前读锁,这保证了主库的某个chunk内部数据的一致性。否则,1000个人chekcusm同样的1000行数据,可能得到1000个不同的结果,你无法避开mvcc的干扰!获得for update锁后,pt工具开始计算chunk的checksum值,并把计算结果保存到pt工具自建的结果表中(采用replace into select的方式),然后释放锁。该语句最终会传递到从库并执行相同的计算逻辑。

内部工作过程

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

重要选项

安全选项:
–check-replication-filters 是否检查复制过滤规则
–check-slave-tables 检查是否所有从库都有被检查的表和列
–chunk-size-limit 每个chunk最大不能超过这个大小,超过就忽略它

限速选项:
–check-interval 多久检查一次主从延迟、主库负载是否达到上限
–check-slave-lag 是否只检查这个从库的延迟
–max-lag 最大延迟,超过这个就等待
–max-load 最大负载,超过这个就等待

过滤选项:
–databases 只检查某些库
–tables 只检查某些表
这些过滤选项在修复不一致数据后,检查修复效果很有用。

其他选项
–resume 因某种原因中断,下次接着执行,不用从头开始
–chunk-time 每个chunk被计算的时间,一般默认为0.5秒

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注