pt-table-checksum

pt-table-checksum,第1张

概述pt-table-checksum是percona公司提供的一个用于在线比对主从数据一致性的工具。 实现原理 将一张大表分成多个chunk,每次针对一个chunk进行校验,同时将校验的结果通过REPL

pt-table-checksum是percona公司提供的一个用于在线比对主从数据一致性的工具。

 

实现原理

将一张大表分成多个chunk,每次针对一个chunk进行校验,同时将校验的结果通过REPLACE INTO语句写入到percona.checksums表中,然后该语句通过主从复制,在SLAVE中同样执行一次,校验的结果同样是写入到percona.checksums表中,最后,通过查询percona.checksums来获取主从不一致的信息。

 

常见用法

1. 基本用法

# pt-table-checksum -h192.168.244.10 -umonitor -pmonitor123

其中,monitor的最小权限如下(第二个权限是针对percona.checksums的):

GRANT SELECT,PROCESS,SUPER,REPliCATION SLAVE,REPliCATION CLIENT ON *.* TO 'monitor'@'192.168.244.10';

GRANT ALL PRIVILEGES ON `percona`.* TO 'monitor'@'192.168.244.10';

2. pt-table-checksum默认是运行在statement下,如果是其它日志格式,需加--no-check-binlog-format参数

# pt-table-checksum -h192.168.244.10 -umonitor -pmonitor123 --no-check-binlog-format

3. 如果主从复制中加了过滤条件,譬如binlog_ignore_db或replicate_do_db之类的参数,需加--no-check-replication-filters参数

# pt-table-checksum -h192.168.244.10 -umonitor -pmonitor123 --no-check-binlog-format --no-check-replication-filters

   如果在对被过滤表进行校验时,命令hang住了,可加--replicate-database参数。

4. 基于指定库的校验

# pt-table-checksum -h192.168.244.10 -umonitor -pmonitor123 --no-check-binlog-format --databases=test,test1

5. 基于指定表的校验

# pt-table-checksum -h192.168.244.10 -umonitor -pmonitor123 --no-check-binlog-format --tables=test2.test

其它具体用法,可参考另外一篇博客:pt-table-checksum参数详解

 

通过打开general_log来看看其具体的执行过程,注意,测试表是test.test,共1000000条记录。

17 query    SHOW GLOBAL STATUS liKE 'Threads_running'
查看Threads_running变量是为了查看当前系统的负载情况
17 query /*!40101 SET @olD_sql_mode := @@sql_mode,@@sql_mode := '',@olD_QUOTE := @@sql_QUOTE_SHOW_CREATE,@@sql_QUOTE_SHOW_CREATE := 1 */
设置会话变量
17 query USE `test` query SHOW CREATE table `test`.`test`
查看test表的表结构,选取分片键,一般为主键或唯一索引
!40101 SET @@sql_mode := @olD_sql_mode,@@sql_QUOTE_SHOW_CREATE := @olD_QUOTE */17 query EXPLAIN SELECT * FROM `test`.`test` WHERE 1=1
查看test表的大概数量17 query SELECT !40001 sql_NO_CACHE */ `ID` FROM `test`.`test` FORCE INDEX(`PRIMARY`) ORDER BY `ID` liMIT 1 first lower boundary*/
选择第一个chunk的下标,即ID的最小值*/ `ID` FROM `test`.`test` FORCE INDEX (`PRIMARY`) WHERE `ID` IS NOT NulL ORDER BY `ID` liMIT key_len*/
查看索引的长度17 query EXPLAIN SELECT */ * FROM `test`.`test` FORCE INDEX (`PRIMARY`) WHERE `ID` >= 1' */
查看实际使用的索引的长度,这个针对联合索引的场景。
query USE `percona`17 query DELETE FROM `percona`.`checksums` WHERE db = test' AND tbl = '
从percona.checksums表中删除之前的校验记录
*/ `ID` FROM `test`.`test` FORCE INDEX(`PRIMARY`) WHERE ((`ID` >= ')) ORDER BY `ID` liMIT 2171,2 next chunk boundary*/
17
query SELECT next chunk boundary*/ 确认本chunk的上限,以及下一个chunk的下限。
17 query EXPLAIN SELECT COUNT(*) AS cnt,COALESCE(LOWER(CONV(BIT_XOR(CAST(CRC32(CONCAT_WS(#',`ID`,`ip`,`no`,CONCAT(ISNulL(`ip`),ISNulL(`no`)))) AS UNSIGNED)),1)">10,1)">16)),1)">0) AS crc FROM `test`.`test` FORCE INDEX(`PRIMARY`) WHERE ((`ID` >= ')) AND ((`ID` <= 2172')) explain checksum chunk 查看对本次chunk执行checksum *** 作的执行计划,确认读取的行数是否合理,选择的索引是否合适
17
query REPLACE INTO `percona`.`checksums` (db,tbl,chunk,chunk_index,lower_boundary,upper_boundary,this_cnt,this_crc) SELECT PRIMARYchecksum chunk*/ 关键 *** 作,对本次chunk执行checksum *** 作,并将结果更新到percona.checksums表中。
query SHOW WARNINGS17 query SELECT this_crc,this_cnt FROM `percona`.`checksums` WHERE db = ' AND chunk = '
查看本次 *** 作校验的行数和校验和17 query UPDATE `percona`.`checksums` SET chunk_time = 0.059603568c1ba3' WHERE db = ' 将上面那个查询得到的行数和校验和更新到master_cnt和master_crc中。这样的话,主库的校验和在从库执行replace *** 作时被覆盖。

下面是针对第二个chunk执行的 *** 作。'217318219,1)">2039217 query REPLACE INTO `percona`.`checksums` (db,1)">20.0229608337136518220'... 下面的校验和上面的并不相同,上述ID值的范围是1~1000000,下面两个chunk的范围是<1和>1000000,为什么要这么做呢?
主要是考虑到从库有可能存在上述两个范围的数据。
17 query EXPLAIN SELECT COUNT(*),1)">0' FROM `test`.`test` FORCE INDEX(`PRIMARY`) WHERE ((`ID` < ')) ORDER BY `ID` explain past lower chunk9past lower chunk0.004492'' FROM `test`.`test` FORCE INDEX(`PRIMARY`) WHERE ((`ID` > 1000000explain past upper chunk10past upper chunk0.058622'

 

输出结果说明

# pt-table-checksum -h 192.168.244.10 -umonitor -pmonitor123 --no-check-binlog-format

            TS ERRORS  DIFFS     ROWS  CHUNKS SKIPPED    TIME table11-09T21:19:01      0      0        0       1       0   2.768 h2.h306      3.903 hello.h10.620 hello.h210      1.725 MysqL.columns_priv1        4       0.457 MysqL.db11      0.306 MysqL.event12      0.721 MysqL.func13      40       0.649 MysqL.help_category14      611       6       1.313 MysqL.help_keyword18      0     1218       3.432 MysqL.help_relation20      583       1.632 MysqL.help_topic21      0.501 MysqL.ndb_binlog_index0.319 MysqL.plugin22      0.624 MysqL.proc0.626 MysqL.procs_priv23      2       0.375 MysqL.proxIEs_priv24      0.806 MysqL.servers3       0.292 MysqL.tables_priv0.382 MysqL.time_zone25      0.398 MysqL.time_zone_leap_second0.386 MysqL.time_zone_name0.393 MysqL.time_zone_Transition26      0.313 MysqL.time_zone_Transition_type18        MysqL.user27      0.642 percona.dsns30      41       2.613 test.checksum31      0.669 test.ta20:1  1000000       7       0  42.009 test.test15      5       1.818 test1.test16      0.546 test1.test117      12       0.508 test2.test0.387 test2.test21     1000       0.707 test3.test3

TS:校验完表后的时间戳

ERRORS:校验过程中出现的errors和warnings的次数。

DIFFS:所有SLAVE中checksum值不相同的chunk的数量,如一主两从中,SLAVE1的chunk1与MASTER的checksum不同,SLAVE2的chunk1和chunk2不相同,则DIFFS的值为2。如果SLAVE2的chunk2和chunk3不相同,则DIFFS为3。

ROWS:表中校验的记录数。通常情况下为表的总行数。如果指定了--where选项,则为符合条件的记录数。

CHUNKS:表被分割为多个chunk后,chunk的个数。

SKIPPED:跳过的chunk的个数,通常因为如下原因:

* MysqL not using the --chunk-index* MysqL not using the full chunk index (--[no]check-plan)* Chunk size is greater than --chunk-size * --chunk-size-limit* Lock wait timeout exceeded (--retrIEs)* Checksum query killed (--retrIEs)

TIME:校验表所花费的时间。

table:校验的表名

 

replicate-check-only参数下的输出结果说明 

如果指定了--replicate-check-only参数,则意味着不会校验任何表,直接获取上次校验的结果。

# pt-table-checksum -h 192.168.244.10 -umonitor -pmonitor123 --no-check-binlog-format --replicate-check-only

Differences on hbasetable CHUNK CNT_DIFF CRC_DIFF CHUNK_INDEX LOWER_BOUNDARY UPPER_BOUNDARYMysqL.db 1 1   MysqL.tables_priv 1 -3    MysqL.user 4    test.checksum 0    Differences on testtable CHUNK CNT_DIFF CRC_DIFF CHUNK_INDEX LOWER_BOUNDARY UPPER_BOUNDARYMysqL.db 2    test.test 7 1000000 0 PRIMARY 1000000 test2.test 10    test2.test2    test3.test3 2000 1   

可以看出,它分别输出了不同SLAVE中的差异部分。

table:校验的表名。

CHUNK:checksum值不相同的chunk的数量。

CNT_DIFF:The number of chunk rows on the replica minus the number of chunk rows on the master.即SLAVE中被校验的记录数减去MASTER中的记录数。

CRC_DIFF:1 if the CRC of the chunk on the replica is different than the CRC of the chunk on the master,else 0.如果校验值相同,则CRC_DIFF为0,否则为1。

上述test.test中CRC_DIFF中crc为0的原因是SLAVE比MASTER多1000000条记录,且这1000000条记录正好又是在最后一个chunk中(如下所示)。注:master中ID最大值为1000000。

319 query     REPLACE INTO `percona`.`checksums` (db,this_cnt,this_crc) SELECT 7*/

CHUNK_INDEX:用于将table切割成chunk的索引。

LOWER_BOUNDARY:The index values that define the lower boundary of the chunk.

UPPER_BOUNDARY:The index values that define the upper boundary of the chunk.

上述两个参数可用来定位具有不同checksum值的chunk对应的索引的上限和下限。

 

总结

1. pt-table-checksum对表进行校验时,并不需要表上面有任何索引。这时候,整张表即是一个chunk。

REPLACE INTO `percona`.`checksums` (db,this_crc) SELECT 'test2t11NulL,1)">COUNT(*) AS cnt,1)">COALESCE(LOWER(CONV(BIT_XOR(CAST(CRC32(CONCAT_WS(#ISNulL(`ID`),1)">ISNulL(`name`)))) AS UNSIGNED)),1); Font-weight: bold">10,1); Font-weight: bold">16)),1); Font-weight: bold">0) AS crc FROM `test2`.`t1` checksum table*/ 

   如果表的行过多的话,它会报如下错误:

# pt-table-checksum -h192.168.244.10 -umonitor -pmonitor123 --chunk-size-limit=100 --no-check-binlog-format --tables=test2.t1

11-17T11:41:53 Cannot checksum table test2.t1: There is no good index and the table is oversized. at /usr/local/bin/pt-tablechecksum line 6528.

解决方法:

调整chunk-size-limit的值

# pt-table-checksum -h192.168.244.10 -umonitor -pmonitor123 --chunk-size-limit=1000 --no-check-binlog-format --tables=test2.t1

            TS ERRORS  DIFFS     ROWS  CHUNKS SKIPPED    TIME table59      0      0   100004       1       0.600 test2.t1

 

 

  

   

 

总结

以上是内存溢出为你收集整理的pt-table-checksum全部内容,希望文章能够帮你解决pt-table-checksum所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/sjk/1151574.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存