pt-table-checksum使用方法及主从一致性校验

软件介绍

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

原理

  • 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完成对一个表的所有分块的校验后,它会暂停并等待所有检测到的从库执行完这个表的校验语句。一旦从库执行完成,它会比对主、从的校验结果是否一致,并输出一行结果。

使用限制

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

输出

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

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

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

输出格式如下:

1
2
3
            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参数,则只会输出校验结果不一致的从库数据。
输出结果的格式为:每一个从库为一个段落,每一个校验结果不同的分块占一行,各列值之间以空格分隔。如下:

1
2
3
4
5
6
7
8
9
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
    分块的上边界所使用的索引值。

退出状态码

pt-table-checksum的退出状态码有3种值:0255其他的位掩码值

  • 0表示没有校验过程中没有任何错误出现。即,没有错误、警告、不同的校验值、跳过数据分块或表等。
  • 255表示数据校验出现严重错误。也就是说,校验的进程终止或崩溃了。错误信息作为标准错误(STDERR)输出。
  • 如果退出状态码不是0或255,各个位掩码值表示的含义如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
      FLAG              BIT VALUE  MEANING
      ================  =========  ==========================================
      ERROR                     1  出现了一个不严重的错误
      ALREADY_RUNNING           2  --pid选项指定的文件已存在,并且对应的PID在运行中
      CAUGHT_SIGNAL             4  Caught SIGHUP, SIGINT, SIGPIPE, or SIGTERM
      NO_SLAVES_FOUND           8  没有检测到从库或集群节点
      TABLE_DIFF               16  本次校验至少有一个分块的数据不同
      SKIP_CHUNK               32  至少有一个数据分块被跳过
      SKIP_TABLE               64  至少有一个表被跳过

常用参数

–ask-pass

通过提示输入密码,而不是在命令行指定密码。

–[no]check-binlog-format

默认:yes
检查binlog格式。
如果binlog格式不是STATEMENT,需要指定--no-check-binlog-format,如果不指定此项,会报错。

–[no]check-replication-filters

默认:yes
pt-table-checksum会检查复制过滤相关的参数,例如,binlog_ignore_dbreplicate_do_db等。如果检测到已配置任何复制过滤参数,它将会终止校验,并输出错误信息。

如果只是校验指定的数据库或表,且没有被复制过滤掉,则可以指定--no-check-replication-filters来进行数据校验。
如果被校验的表在主库存在,但是在从库被复制过滤掉了,则会导致复制中断卡住。

–chunk-time

值类型:浮点数
默认:0.5(s)
根据这个时间来动态的调整数据分块的大小,以使每个分块的校验执行时间不超过此值。

–databases

缩写形式:-d
指定需要校验的数据库,多个库以逗号分隔。

–databases-regex

使用正则表达式的形式来指定需要校验的数据库。

–host

缩写形式:-h
值类型:字符串
默认:localhost

需要连接的服务器的主机地址。

–ignore-databases

指定需要忽略校验的数据库,多个库以逗号分隔。

–ignore-databases-regex

值类型:字符串
以正则表达式的形式指定需要忽略的数据库。

–ignore-tables

指定需要忽略校验的表,多个表名以逗号分隔。表名前面可以指定数据库名。
--replicate选项指定的表,始终会被忽略掉。

–ignore-tables-regex

以正则表达式的形式指定需要忽略校验的表。

–password

缩写形式:-p
数据库连接的密码,如果密码包括逗号(,),则必须使用反斜杠。

–port

缩写形式:-P
数据库连接的端口。

–recursion-method

默认:processlist,hosts
指定搜索从库的递归方法。当pt-table-checksum无法搜索到从库时,其可以正常的进行数据校验,但是无法直接检测从库数据与主库是否一致。
如果搜索不到从库,可以尝试指定其他的递归方法,或者使用dsn来指定需要检测的从库。

允许的方法有:

1
2
3
4
5
6
7
METHOD       USES
===========  =============================================
processlist  SHOW PROCESSLIST
hosts        SHOW SLAVE HOSTS
cluster      SHOW STATUS LIKE 'wsrep\_incoming\_addresses'
dsn=DSN      DSNs from a table
none         Do not find slaves

详细可参考官方文档:https://www.percona.com/doc/percona-toolkit/2.2/pt-table-checksum.html#cmdoption-pt-table-checksum--recursion-method

–replicate

默认:percona.checksums
将校验结果写入到指定的库和表中。

本文后续所说的校验信息表即指该表。

表结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CREATE TABLE checksums (
   db             CHAR(64)     NOT NULL,
   tbl            CHAR(64)     NOT NULL,
   chunk          INT          NOT NULL,
   chunk_time     FLOAT            NULL,
   chunk_index    VARCHAR(200)     NULL,
   lower_boundary TEXT             NULL,
   upper_boundary TEXT             NULL,
   this_crc       CHAR(40)     NOT NULL,
   this_cnt       INT          NOT NULL,
   master_crc     CHAR(40)         NULL,
   master_cnt     INT              NULL,
   ts             TIMESTAMP    NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
   PRIMARY KEY (db, tbl, chunk),
   INDEX ts_db_tbl (ts, db, tbl)
ENGINE=InnoDB DEFAULT CHARSET=utf8;

lower_boundaryupper_boundary列的类型可以设置为BLOB,详情参考--binary-index参数。

默认情况下,--[no]create-replicate-table是开启的。因此,当--replicate指定的库和表不存在时,pt-table-checksum会自动创建这些库和表。

如果用于校验的MySQL用户没有新建表的权限,则也可以在校验主从数据之前,使用上述表结构手动创建该表。

--replicate参数指定的表,在校验数据一致性时,默认是被忽略的。即,--ignore-tables参数会自动的包含该表。

–[no]replicate-check

默认:yes
在校验完每一个表后,校验从库与主库的数据一致性。
pt-table-checksum会在所有检测到的从库上,执行一个简单的SELECT语句,来比较从库的校验值与主库的校验值是否一致。如果不一致,则将不一致的分块的数量,输出到DIFFS列。

–replicate-check-only

如果指定此选项,pt-table-checksum不会校验任何表,而是使用上一次数据校验存储在--replicate指定的校验信息表的校验数据,来检测主从数据的一致性。
使用该选项时,只会输出校验结果不一致的表的信息。

该选项只和--[no]replicate-check选项搭配使用。这两个选项配合起来可以做定时校验和监控。例如,使用cron任务定时校验主从数据时指定--no-replicate-check,然后再在Zabbix或Nagios监控时,指定--replicate-check-only来检测主从数据一致性。

–slave-user

值类型:字符串
连接从库时所使用的MySQL用户名。
当连接从库的用户名和主库不同时,可以使用此参数单独指定从库用户。

–slave-password

值类型:字符串
指定连接从库的密码,可以和参数--slave-user一起使用,并且所有从库的密码都必须是一样的。

–set-vars

值类型:array
设置MySQL变量值,每个变量值的形式为variable=value,多个变量以逗号分隔。
pt-table-checksum默认设置的变量值为:

1
2
wait_timeout=10000
innodb_lock_wait_timeout=1

当无法设置变量值的时候,pt-table-checksum会输出相应的警告信息,并继续进行校验。

–socket

缩写形式:-S
指定socket文件。

–tables

缩写形式:-t
指定需要检查的表,多个表用逗号分隔。表名前面可以加上数据库的名称。

–tables-regex

使用正则表达式的形式指定需要检查的表。

–user

缩写形式:-u

指定连接的用户名。

–where

只校验符合WHERE条件的数据。

通常情况下,如果某个表每天只会往里面新增写入数据,则可以使用WHERE条件只校验昨天的数据,以加快校验速度。
如:

1
pt-table-checksum --where "ts > CURRENT_DATE - INTERVAL 1 DAY"

其他参数

–binary-index

该参数选项和--create-replicate-table选项一起使用,使用该参数会将校验信息表的lower_boundaryupper_boundary列定义为BLOB类型。
如果被校验的表的索引包含binary数据类型,则需要使用选项。

–check-interval

值类型:时间
默认:1
当发现从库的延迟时间超过--max-lag定义的时间后,需要休眠等待的时间。

–[no]check-plan

默认:yes
在执行查询语句之前使用EXPLAIN检查执行计划,以保证校验工作的安全性。
查询语句包括确定表数据分块的上下边界的语句,和查询分块的语句。如果MySQL将使用一个糟糕的执行计划,pt-table-checksum会跳过这个分块。

–check-slave-lag

值类型:字符串
指定需要检测复制延迟的从库,参数值是一个DSN,并且继承主库的属性和连接选项(--port--user等)。
默认情况下,pt-table-checksum会监测所有从库的延迟。如果某些从库配置了延迟复制,则可以使用此参数指定只需要检测延迟的从库,以忽略那些配置了复制延迟的从库。

–[no]check-slave-tables

默认:yes
检查主库的表存在于从库上,且具有--columns选项指定的所有的列。
如果从库上不存在某些表,或者缺少某些列,在校验数据一致性的时候,pt-table-checksum将会导致复制中断。
如果确定从库的表和列都和主库的一样,则可以禁用此项。

–chunk-index

值类型:字符串
指定将表进行分块所使用的索引。
默认情况下,pt-table-checksum会自动选择最合适的索引来对表进行分块。使用此选项可以使用指定的索引。如果指定的索引不存在,则pt-table-checksum会使用其默认的行为来选择索引。
建议在校验单表数据时可以使用此参数,而不要在校验整个服务器的数据时使用此参数。

–chunk-index-columns

值类型:整数
和参数--chunk-index一起使用,指定只使用指定(复合)索引的最左边的几列。

–chunk-size

默认:1000
每一个数据分块的行数。允许的后缀有:kMG
推荐在大多数情况下,不要使用此参数,而是使用--chunk-time参数。

使用该参数可能会引起一个问题:

如果分块所使用的索引不是唯一的,则可能导致分块的行数比实际指定的要大得多。
例如,一个分块使用索引可以检索到的行数为10000,则使用该索引的WHERE语句是无法正好匹配1000条记录的,那么这个分块就会包含10000行记录。
这样的分块,很可能会由于超过--chunk-size-limit的限制而被跳过。

–chunk-size-limit

值类型:浮点数
默认:2.0
指定分块的行数最多可以超过--chunk-size参数指定的行数的多少倍。

pt-table-checksum使用EXPLAIN来估算分块的行数。如果这个估算值超过了--chunk-size参数值的某个倍数(由--chunk-size-limit定义),则分块会被跳过。

最小值是1,表示分块的行数不能超过--chunk-size指定的值。由于分块的行数是估算的,所以不建议指定为1。
当参数值为0时,则不会检查是否超过指定的行数。

–columns

缩写形式:-c
值类型:array
多个列以逗号分隔。只校验这些列。如果一个表不包含该选项指定的任何一列,则会被跳过。
该选项对所有的表有效,所以一般在进行单表校验时,指定此选项才是有意义的,除非被校验的多个表具有相同的列。

–config

值类型:array
指定配置文件,多个值以逗号分隔。
如果使用该参数,该选项必须放在第一个位置。

–[no]create-replicate-table

默认:yes
如果--replicate选项指定的数据库和表不存在,则创建该库和表。表结构与--replicate选项下提到的表结构一样。

–defaults-file

缩写形式:-F
只从给定的文件读取MySQL的参数。必须使用绝对路径来指定。

–[no]empty-replicate-table

默认:yes
在校验每个表之前,删除之前存在校验信息表的该表的校验数据。

该选项不会TRUNCATE整个表,而只是在校验每个表之前,删除该表相关的校验数据。
如果使用--resume选项从之前的一个校验继续执行校验,则重新开始校验时所在的那张表的校验数据不会被清除掉。

–engines

缩写形式:-e
指定需要校验的表的存储引擎。

–explain

可以多次使用该参数选项。默认是0次。
输出当前数据校验的查询语句,但不执行。该选项会使--[no]empty-replicate-table选项无效。
当使用该参数一次时,会输出表的校验查询语句(不含具体的上下边界值)。
当使用该参数两次时,会迭代的调用数据分块算法,输出表的每一个分块的上、下边界值,但是不会执行这些校验查询语句。

–float-precision

值类型:整数
FLOATDOUBLE类型转换成字符串时的精度。
指定浮点数被四舍五入(ROUND())转换成字符串时,小数点后保留的数字的个数。
默认情况下,浮点数没有被四舍五入,而是被使用CONCAT()函数转换成字符串。

–function

值类型:字符串
校验时使用的hash函数,包括FNV1A_64MURMUR_HASHSHA1MD5CRC32等。
默认的是CRC32

–help

显示帮助信息。

–ignore-columns

指定需要忽略校验的列名,多个列以逗号分隔。
如果一个表的所有列都在--ignore-columns指定忽略的列中,则会跳过该表。

–ignore-engines

默认:FEDERATED,MRG_MyISAM
指定需要忽略校验的存储引擎,多个值以逗号分隔。

–max-lag

类型:时间
默认:1s

当发现从库的延迟超过该参数的值时,则会暂停校验,直至从库的延迟小于该值。
pt-table-checksum在校验完每一个分块后,都会检查所有检测到的从库的延迟(根据Seconds_Behind_Master判断)。如果延迟大于该值,则会休眠等待--check-interval定义的秒数,然后再次检查从库。
如果从库停止了,pt-table-checksum则会一直等待,直至从库重新启动。当从库重新启动且延迟不再大的时候,会继续进行校验。

–max-load

值类型:array
默认:Threads_running=25
在校验完每一个分块后,执行SHOW GLOBAL STATUS,检查相关状态的值是否超过该选项定义的阈值。当超过阈值时,pt-table-checksum会暂停校验;当值低于阈值后,会继续进行校验。
该选项支持指定多个MySQL status变量(以逗号分隔),并为其分别指定阈值(可选的。形式:=MAX_VALUE:MAX_VALUE)。如果没有指定阈值,则pt-table-checksum会将当前值增大20%,作为阈值。
例如,可以指定Threads_connected=110,来限定当Threads_connected超过110时,则暂停校验。

–pid

创建指定的PID文件。

–progress

type:array
默认值:time,30
每隔多久将执行的进度信息以标准错误输出(STDERR)。
该参数的值由两部分构成,以逗号分隔。第一部分的取值可以是:percentagetime,或者iterations;第二部分指定每隔多久进行一次信息输出:in percentage,seconds,或者number of iterations。
pt-table-checksum会对许多耗时的操作输出进度信息,包括等待从库赶上主库(从库延迟时)。

–quiet

缩写形式:-q
可以多次叠加使用该选项,默认未使用。使用该选项使pt-table-checksum只输出最重要的信息,并且会使选项--progress无效。
指定该参数一次,则只会输出错误、警告,和具有不同校验值的表。
指定该参数两次,则只会输出错误信息。在这种情况下,可以使用退出状态码来判断是否有警告或者不同的校验值。

–recurse

值类型:整数
在主从结构中,递归搜索从库的层数。
默认是无限的。

–replicate-check-retries

值类型:整数
默认:1
当发现某个表的校验结果不一致时,对该表进行重复校验的次数。只有当经过这些次数的校验后,还存在的不一致的校验信息才作为最终的结果。

使用这个参数,是为了解决使用-–resume参数而导致的虚假的主从不一致信息。当该参数值为2或者更大时,基本可以消除这些虚假的主从不一致信息。
详情可以参考以下链接:

–replicate-database

pt-table-checksum在进行数据校验时,执行的USE database语句始终使用该参数指定的数据库。
默认情况下,会将当前校验的表所在的库,作为USE database的库来执行。
使用该参数选项来避免复制过滤引起的问题(过滤参数如binlog_ignore_dbreplicate_ignore_db等)。

–resume

在上一次校验中断后,使用此参数可以继续上一次的校验。该参数会禁用--[no]empty-replicate-table参数。
如果pt-table-checksum在校验完所有的表之前被终止了,则使用--resume参数再次启动pt-table-checksum时,会从上次校验的最后一个表的最后一个校验完成的分块开始校验。

–retries

值类型:整数
默认:2

当出现一个非致命的错误时,对该分块进行重试校验的次数。
非致命的错误包括锁等待超时、校验查询的SQL线程被kill了,等等。

–run-time

值类型:时间
pt-table-checksum执行校验的总时长。
允许的时间后缀有:s(秒),m(分),h(时),d(天)。

当校验很多表时,可以将该参数和--resume参数结合在一起使用。

使用--run-time在指定分配的时间进行校验后退出,然后使用--resume参数在指定时间继续之前的校验。

–separator

值类型:字符串
默认:#
定义函数CONCAT_WS()使用的分隔符。该参数定义的字符,用于在校验时连接各列的值。

–slave-skip-tolerance

值类型:浮点数
默认:1.0

当某个表在主库只被作为一个数据分块校验,而在从库的数据大小却超过了可接受的最大值时,该表会被跳过。由于表的行数是粗略估计的,在多数情况下,由于很小的主从数据差异而进行的表跳过是没有必要的。
该参数的定义可以减少这种不必要的跳过。
使用该参数可指定从库的行数超过主库的行数的最大的容忍值。
例如,当参数值为1.2时,表在从库的行数最多是主库的1.2倍。

–trim

对校验数据的VARCHAR列添加TRIM()函数。
MySQL 5.0之后的版本,VARCHAR列会保存字符串首尾的空格;但是MySQL 5.0之前的版本会移除这些空格。
指定该选项,可以移除VARCHAR列数据的首尾的空格。

–version

显示程序的版本。

–[no]version-check

默认:yes
自动的检查Percona Toolkit,MySQL,和其他程序的版本。
首先,pt-table-checksum会检查它自己和其他软件的版本,检查的软件如MySQL、Perl、Perl module DBD::mysql等等。然后,它会检查和输出这些软件版本的已知问题。

使用示例

用法

1
pt-table-checksum [OPTIONS] [DSN]

系统环境

  • OS Version: CentOS 6
  • DB Version: MySQL 5.6.29
  • PT Version: pt-table-checksum 2.2.18
  • 主从环境:
    主从端口相同,都是3376。
    • Master: 192.168.0.162:3376
    • Slave1: 192.168.0.161:3376

安装依赖软件

安装 Perl, DBI, DBD::mysql等

1
shell> yum install perl perl-devel perl-Time-HiRes perl-DBI perl-DBD-MySQL perl-Digest-MD5

安装Percona Toolkit

1
2
3
4
5
shell> wget percona.com/get/percona-toolkit.tar.gz
shell> tar zxvf percona-toolkit.tar.gz
shell> cd percona-toolkit-2.2.18
shell> ./bin/pt-table-checksum --version
pt-table-checksum 2.2.18

新建MySQL帐号

新建账号pt_table_check用于连接主库和从库进行校验:

1
2
mysql> GRANT SELECT, PROCESS, SUPER, REPLICATION SLAVE ON *.* TO pt_table_check@'%' IDENTIFIED BY 'checksum123';
mysql> GRANT CREATE, INSERT, UPDATE, DELETE ON percona_schema.* TO pt_table_check@'%';

执行数据校验

在主库上执行

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

1
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

结果:

1
2
            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列看出有一个数据分块的主从数据不一致。

查看差异汇总

在从库执行

1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> SELECT db, tbl, SUM(this_cnt) AS total_rows, COUNT(*) AS chunks
FROM percona_schema.checksums
WHERE (
 master_cnt <> this_cnt
 OR master_crc <> this_crc
 OR ISNULL(master_crc) <> ISNULL(this_crc))
GROUP BY db, tbl;
+-------------+-------+------------+--------+
| db          | tbl   | total_rows | chunks |
+-------------+-------+------------+--------+
| road_to_dba | t_int |         10 |      1 |
+-------------+-------+------------+--------+
1 row in set (0.00 sec)

从以上查询结果可以看出:

表road_to_dba.t_int总共有一个分块(chunks)的主从数据不一致。

或者

1
2
3
4
5
6
7
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

参考文档