2.pt-table-checksum工具

1.前言

pt-table-checksum是Percona Toolkit工具系列中的一个,可以用来检测MySQL主、从数据的一致性。
其原理是,在主库执行校验语句(binlog格式为STATEMENT),通过复制传递到从库,如果数据不一致,则主、从会产生不同的校验值,以此来判断主从数据是否一致。

2.原理

    • pt-table-checksum将每个表切分成多个块(chunks),每个块包含多行数据,每次仅对一个块进行校验。
    • 它可以根据参数指定的每个块的校验执行时间,将表分成不同大小的块。
    • 将单个表切分成多个块进行校验,可以保证不会引起从库太大的延迟,也不会对服务器负载造成太大干扰。默认的每个块的校验执行时间是0.5s。
    • pt-table-checksum会持续跟踪服务器执行校验语句的时间,并且会随着服务器性能的变化,来动态调整分块的大小。
    • 将表分块时,需要使用索引(优先使用主键或唯一键)。如果表没有索引,且表的行数量较小时,pt-table-checksum会将整个表作为一个数据块进行校验。
    • pt-table-checksum会持续监控从库状态,如果从库复制延迟太大,校验会暂停,以等待从库追上主库。如果从库发生错误,或者复制停止,它也会暂停及等待。
    • pt-table-checksum对于校验过程中产生的错误是有复原能力的。如果正在执行校验的SQL被kill掉,这对pt-table-checksum来说不是一个致命的错误,它会重新执行被kill掉的查询语句;如果再次失败,则会跳过,继续进行表的下一个分块的校验。
      当出现锁等待超时的时候,也会进行相同的重试行为,同时输出警告信息。
      如果连接服务器失败,pt-table-checksum也会进行重连和继续进行校验。
    • 当在运行的过程中被完全终止后,可以使用--resume
      参数,继续从上次终止时正在处理的表的当前分块开始,继续校验。
      我们也可以使用CTRL-C
      按键来停止校验,pt-table-checksum会在完成对当前正在处理的分块的校验后,正常退出。之后我们也可以启动程序继续进行校验。
    • 当pt-table-checksum完成对一个表的所有分块的校验后,它会暂停并等待所有检测到的从库执行完这个表的校验语句。一旦从库执行完成,它会比对主、从的校验结果是否一致,并输出一行结果

3.使用限制  

    • pt-table-checksum要求复制是基于STATEMENT格式的,并且它在运行时会在主库上设置binlog_format=STATEMENT
      ,但是由于MySQL的限制,这一设置并不会传递到从库。
      因此当从库的binlog格式是ROW格式时,无法直接对从库的从库进行校验。
      pt-table-checksum会自动检测所有服务器的binlog_format
      ,可以通过参数--[no]check-binlog-format
      来指定检测与否。
    • pt-table-checksum假设主从的数据库和表结构都是一致的。
      如果主库上的库不存在于从库上,或者从库的表结构与主库不一致,将会导致主从复制中断。

4.参数详见

  https://www.percona.com/doc/percona-toolkit/3.0/pt-table-checksum.html#options

 

5.命令使用(以实践过)

pt-table-checksum  -upt_table_check -p123 -S mysql.sock --tables=liulin.t1 --no-check-binlog-format --replicate=percona_schema.checksums  --recursion-method=hosts

注意1:-u :用户命令 -p 用户密码 -->这里最好在主库创建创建一个用户,然后通过主从复制同步到各个从库中
注意2: --replicate 参数表示在主库和从库下的percona_schema库下创建一张checksums表,该表很重要,一般是在我们执行完命令后,通过主从库的这张表进行验证主从库数据是否一致
注意3: --recursion-method=hosts :这个参数表示主库通过hosts连接和认证从库,注意当开启这个参数时,必须要在从库中配置:report_host参数和report_port参数,填写当前数据库的ip地址和端口号

 

6.输出

pt-table-checksum的输出有两种格式:带--replicate-check-only
参数和正常不带这个参数时,输出结果的格式是不同的。

不带--replicate-check-only 参数输出

pt-table-checksum在完成校验后会以表格形式输出结果,每个表的校验结果为一行输出,每完成校验一张表会输出一行校验结果。

输出格式如下:

    TS ERRORS  DIFFS     ROWS  CHUNKS SKIPPED    TIME TABLE
09-12T10:34:38      0      0        1       1       0   0.059 road_to_dba.names
09-12T10:34:38      0      0        5       1       0   0.016 road_to_dba.t_bigint

各列的含义如下:

    • TS
      pt-table-checksum完成该表的校验时的时间。
    • ERRORS
      在校验表的过程中出现的错误和警告的数量。
      错误和警告信息在校验的过程中会以标准错误的形式输出。
    • DIFFS
      主库数据与一个(或多个)从库数据不一致的分块的数量。
      当指定--no-replicate-check
      时,该值始终为0。当指定--replicate-check-only
      时,只输出数据不一致的表的校验结果。
    • ROWS
      查询和校验的表的行数。
    • CHUNKS
      表被分成的分块的数量。
    • SKIPPED
      校验表时,跳过的分块的数量。
      数据分块被跳过可能由以下问题引起:
      • MySQL没有使用--chunk-index
        指定的索引;
      • 通过分析执行计划(--[no]check-plan
        )检测到MySQL没有使用全部的表分块使用的索引;
      • 数据分块的大小大于--chunk-size * --chunk-size-limit
      • 锁等待超时(重试的次数大于--retries
        指定的值);
      • 校验的查询语句被kill掉(重试的次数大于--retries
        指定的值)
    • TIME
      表的校验执行时长。
    • TABLE
      校验的表名(含库名)。

--replicate-check-only 输出

如果指定了--replicate-check-only
参数,则只会输出校验结果不一致的从库数据。
输出结果的格式为:每一个从库为一个段落,每一个校验结果不同的分块占一行,各列值之间以空格分隔。如下

Differences on node601
TABLE CHUNK CNT_DIFF CRC_DIFF CHUNK_INDEX LOWER_BOUNDARY UPPER_BOUNDARY
road_to_dba.tbl1 1 0 1 PRIMARY 1 100
road_to_dba.tbl1 6 0 1 PRIMARY 501 600
Differences on node603
TABLE CHUNK CNT_DIFF CRC_DIFF CHUNK_INDEX LOWER_BOUNDARY UPPER_BOUNDARY
road_to_dba.tbl1 1 0 1 PRIMARY 1 100
road_to_dba.tbl2 9 5 0 PRIMARY 101 200

输出的每个段落的第一行表示校验结果与主库不一致的从库的信息。
各列的含义如下:

    • TABLE
      与主库数据不一致的表的名称(包含库名)。
    • CHUNK
      表中与主库数据不一致的分块号。
    • CNT_DIFF
      从库的分块的行数量
      减去主库的分块的行数量
      的差值。
    • CRC_DIFF
      如果从库分块的CRC校验值与主库的不同,则为1;否则,为0。
    • CHUNK_INDEX
      将表进行分块所使用的索引。
    • LOWER_BOUNDARY
      分块的下边界所使用的索引值。
    • UPPER_BOUNDARY
      分块的上边界所使用的索引值。

 

7.举例:  

在主库上执行

校验表road_to_dba.t_int主从数据的一致性:

shell> ./bin/pt-table-checksum --socket=/tmp/mysql3376.sock --user=pt_table_check --password=checksum123 --tables=road_to_dba.t_int --no-check-binlog-format --replicate=percona_schema.checksums

结果:

 TS         ERRORS  DIFFS     ROWS  CHUNKS SKIPPED    TIME   TABLE
09-19T18:50:19      0      1        9       1       0     0.042   road_to_dba.t_int

可以从DIFFS列看出有一个数据分块的主从数据不一致

查看差异汇总

在从库执行

mysql> SELECT * FROM percona_schema.checksums WHERE master_cnt <> this_cnt OR master_crc <> this_crc OR ISNULL(master_crc) <> ISNULL(this_crc);
+-------------+-------+-------+------------+-------------+----------------+----------------+----------+----------+------------+------------+---------------------+
| db          | tbl   | chunk | chunk_time | chunk_index | lower_boundary | upper_boundary | this_crc | this_cnt | master_crc | master_cnt | ts                  |
+-------------+-------+-------+------------+-------------+----------------+----------------+----------+----------+------------+------------+---------------------+
| road_to_dba | t_int |     1 |   0.000546 | NULL        | NULL           | NULL           | 2e1ed7d3 |       10 | 17818634   |          9 | 2016-09-19 18:50:19 |
+-------------+-------+-------+------------+-------------+----------------+----------------+----------+----------+------------+------------+---------------------+
1 row in set (0.00 sec)

从以上查询可以看出:

表road_to_dba.t_int的分块1
的主从数据不一致。该分块在主库的行数(master_cnt
)为9
,在从库的行数(this_cnt
)为10
;该分块在主库的校验值(master_crc
)为17818634
,在从库的校验值(this_crc
)为2e1ed7d3

转载于:https://www.modb.pro/db/56033

2.pt-table-checksum工具

上一篇:RDIFramework.NET ━ .NET快速信息化系统开发框架 ━ 工作流程组件WinForm业务平台


下一篇:etcd学习(3)-grpc使用etcd做服务发现