欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

pt-table-checksum 原理解析

发布时间:2025/7/14 编程问答 39 豆豆
生活随笔 收集整理的这篇文章主要介绍了 pt-table-checksum 原理解析 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

Mysql的复制是通过传输binlog来实现,是一种逻辑复制,然而这种复制方式也带来了主从不一致的风险。因此主从不一致的校验对一个DBA来说是至关重要的。perconapt-table-checksum一直作为主从不一致校验的热门工具,让我们现在来一起了解他吧。

pt-table-checksum通过sql在主库执行数据块的校验,然后把相同的语句传送到从库,并在从库上计算数据块的校验,最后将主从库相同块的校验值进行对比,辨别主从不一致。

 

一、事例

pt-table-checksum --nocheck-replication-filters--no-check-binlog-format --replicate=test.checksum --databases=freedomh=127.0.0.1,u=root,P=3301  --tables=a1--chunk_size=100

事例中,本机用root账户登录登录端口为3301的数据库,对freedom数据库的a1表进行主从一致检查,每次检查以100行数据为一个块。

装完pt工具后,运行其中的pt-table-checksum

nocheck-replication-filters:不检查复制过滤器,建议启用。后面可以用--databases来指定需要检查的数据库。

--no-check-binlog-format : 不检查复制的binlog模式,要是binlog模式是ROW

--replicate校验表

--databases –tables 所需检查的数据库名和表名

--chunk_size 块大小定义(即一个块包含的行数)

pt-table-checksum –help 查看还有其他安全参数,限速选项(避免主从延迟太大),过滤选项(可以指定表或数据库)

 

二、内部工作重要过程

  • 1.    SET @@binlog_format := 'STATEMENT'

  • 创建校验信息存放表

  • SET SESSION TRANSACTIONISOLATION LEVEL REPEATABLE READ

  • 查找表的索引列

  • 确定分块的第一行,和分块的最后行索引数值

  • 查出该块的所有记录,并且做校验,最后插入检验表

  • 查出主库校验值和校验行数更新到校验信息表的master_crc, master_cnt列,执行下一个块回到步骤5

  • 通过sql命令查出校验表中主从校验不一致的信息。

  •  

     

    详解:

  • pt-table-checksum通过相同sql在主从库进行计算而校验出来的,所以需要将binlog格式需改成STATEMENT

  • 3.修改隔离级别,通过加锁保证在取数据行数(replaceinto select  from )到计算出检验值这段时间数据不会被修改。他采用块,来减少每次锁住数据的行数,这样提高了并发性。

  • 查出分块区间。首先判断是否为第一个块,如果是的话查找第一个索引值,然后根据第一个索引值查出该快最后个索引值。如果不是第一个块,根据上个块的最后个索引值作为标准,查出该块的第一个索引和最后个索引。

  • 1个块:

    SELECT id` FROM `freedom`.`a1` FORCE INDEX(`PRIMARY`) WHERE `id` IS NOT NULL ORDER BY `id` LIMIT1

    先根据表a1的主键索引排序,然后得到第一个索引值。

    SELECT /*!40001 SQL_NO_CACHE */ `id` FROM`freedom`.`a1` FORCE INDEX(`PRIMARY`) WHERE ((`id` >= '1')) ORDER BY `id`LIMIT 100, 2

    因为块数大小为100,查出该块中最后个索引值的大小。

    2个块:

    SELECT /*!40001 SQL_NO_CACHE */ `id` FROM`freedom`.`a1` FORCE INDEX(`PRIMARY`) WHERE ((`id` > '100')) ORDER BY `id`LIMIT 101, 2

    上个块的最后个索引值为100,查出其后的100个索引值,得到该快的第一个索引和最后个索引。

    6.计算校验值

    先根据该块的索引区间,将该块所有行数据进行合并然后做校验,然后插入检验表。插入检验表的信息有,数据库名,表名,块号,第一个索引,最后个索引,块的行数以及块的内容。

    7. 将主库的校验值更新到主从校验表。

    UPDATE `test`.`checksum` SET chunk_time ='0.002492', master_crc = 'd7ac8fcb', master_cnt = '100' WHERE db = 'freedom'AND tbl = 'a1' AND chunk = '1'

    将主库的校验值更新到主从校验表。

    9. 在从库检查主从不同步。

    select * from test.checksums where master_cnt <>this_cnt OR master_crc <> this_crc OR ISNULL(master_crc) <>ISNULL(this_crc) \G

    查出检验位或行数不同的数据


    三、性能影响

    数据库层面:并发性上,通过块来大大减少锁的影响,从而又能保证数据一致性又能保证检验数据的准确性。主从延迟问题上,因为主库更新可以并发,然而从库Slave_SQL_Running线程是单线程这种速率差异将会导致一个时间段中主从数据不一致,这样将导致检验数据不准确,主库执行sql检验语句再通过复制原理最后从库再执行sql语句,虽然主从执行校验的时间不同但保证了数据的一致性。主从不一致过大,也可以通过限速选项来避免。

       服务器层面:从图表可以看到因为大量计算校验值,cpu消耗量较大。可以通过减少块数的大小来减轻cpu的负载,但需要增加处理时间IO,每个块需要读操作做一次以及写操作两次,对于IO的负载是比较低的。

                           1G数据 200W条数据量
       块数大小      CPU(%)   IO(%)   处理时间(分钟)
       1000 45
       7
        1
        100  28   7    4


    四、注意事项

    1.从库配置表上需要加上,

    report_host=slave_ip
    report_port=slave_port

    不然将报Diffscannot be detected because no slaves were found.错误

    2.表中没有索引,pt-table-checksum将没办法处理

    3.表中只有普通索引。当数据列有重复并且正好在分块的交界中,将会报错。所以表中最好有一个唯一索引列

    01-07T12:05:29 Error checksumming tablefreedom.a6: Possible infinite loop detected! The lower boundary for chunk 2 is <cc, cc> and the lower boundaryfor chunk 3 is also <cc, cc>.  Thisusually happens when using a non-unique single column index.  The current chunk index for table freedom.a6is name which is not unique and covers 1 colum

    4.块的定义过大。当块大于表的行数时,将会产生全表锁。


    转载于:https://blog.51cto.com/10574662/1733788

    《新程序员》:云原生和全面数字化实践50位技术专家共同创作,文字、视频、音频交互阅读

    总结

    以上是生活随笔为你收集整理的pt-table-checksum 原理解析的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。