pt-table-checksum

pt-table-checksum:官方地址

说明

用途:验证MySQL主从复制的表数据是否一致。

语法:

pt-table-checksum [OPTIONS] [DSN]

通过在主从服务器上执行checksum查询,来对比checksump。如果不一致,则​​EXIT STATUS​​​的值为非0。如果检测到表的数据不一致,可以通过​​pt-table-sync​​工具来同步表数据。

相比于老本的​​pt-table-checksum​​​(1.0版本的Toolkit),新版本的​​pt-table-checksum​​​更加简单,没有复杂的校验。更专注于单个数据库,单个表(也就是一次检查一张表)。它一次只能运行一个表,因此在开始校验和之前,它不会累积大量内存或执行大量工作。这使它可以在非常大的服务器上使用。我们在拥有数十万个数据库和表以及数万亿行的服务器上使用它。无论服务器有多大,​​pt-table-checksum​​同样运行良好。

​pt-table-checksum​​会自动检测是否有从库,如果有则会自动连接上去。

支持Percona XtraDB Cluster (PXC) 5.5.28-23.7及更新版本。

限制:

  • 在主从环境中,​​pt-table-checksum​​​要求必须使用基于​​STATEMENT​​​binlog复制,即​​binlog_format=STATEMENT​​。
  • schema和表结构在主从上必须一致,如果不一致复制将会断开。

EXIT STATUS

不同的值代表不同的意思,如下:

FLAG              BIT VALUE  MEANING
================ ========= ==========================================
ERROR 1 A non-fatal error occurred
ALREADY_RUNNING 2 --pid file exists and the PID is running
CAUGHT_SIGNAL 4 Caught SIGHUP, SIGINT, SIGPIPE, or SIGTERM
NO_SLAVES_FOUND 8 No replicas or cluster nodes were found
TABLE_DIFF 16 At least one diff was found
SKIP_CHUNK 32 At least one chunk was skipped
SKIP_TABLE 64 At least one table was skipped

​pt-table-checksum​​执行

具体例子

检查单节点

检查monitor数据库下的所有表,当然意义不大。

[root@BigData ~]# pt-table-checksum h=192.168.20.5,u=root,p=Sanshi_408,P=3306 --databases=monitor
Checking if all tables can be checksummed ...
Starting checksum ...
Diffs cannot be detected because no slaves were found. Please read the --recursion-method documentation for information. ---提示没有检测到从库,这样的检查没啥意义。
TS ERRORS DIFFS ROWS DIFF_ROWS CHUNKS SKIPPED TIME TABLE
08-01T14:01:10 0 0 8 0 1 0 0.042 monitor.B_HOST
08-01T14:01:10 0 0 23 0 1 0 0.071 monitor.B_MONITOR_ITEM
08-01T14:01:11 0 0 7 0 1 0 0.111 monitor.B_SEND_MAIL
08-01T14:01:11 0 0 1 0 1 0 0.088 monitor.B_SEND_MAIL_FREQ
08-01T14:01:11 0 0 7 0 1 0 0.083 monitor.B_TRIGGER_RULE
08-01T14:01:11 0 0 14 0 1 0 0.100 monitor.B_WARN_CONFIG
08-01T14:01:11 0 0 46 0 1 0 0.095 monitor.B_WARN_INFO
08-01T14:01:11 0 0 14 0 1 0 0.066 monitor.B_WARN_ITEM
08-01T14:01:11 0 0 3 0 1 0 0.034 monitor.B_WARN_LEVEL
08-01T14:01:11 0 0 1 0 1 0 0.028 monitor.B_WARN_NOTICE
08-01T14:01:11 0 0 0 0 1 0 0.034 monitor.DATA_GROUP
08-01T14:01:11 0 0 0 0 1 0 0.029 monitor.DATA_GROUP_HOST
08-01T14:01:11 0 0 8 0 1 0 0.036 monitor.DB_GROUP
08-01T14:01:11 0 0 17 0 1 0 0.050 monitor.DB_VERSIONS
08-01T14:01:12 0 0 0 0 1 0 0.062 monitor.FLASH_INFO
08-01T14:01:12 0 0 0 0 1 0 0.042 monitor.FLASH_MONITOR
08-01T14:01:12 0 0 0 0 1 0 0.027 monitor.IBCONF
08-01T14:01:12 0 0 1 0 1 0 0.055 monitor.LICENSE
08-01T14:01:12 0 0 0 0 1 0 0.028 monitor.MARIADB_CONFIG
08-01T14:01:12 0 0 0 0 1 0 0.060 monitor.MARIADB_CONFIG_TYPE
08-01T14:01:12 0 0 0 0 1 0 0.028 monitor.MARIADB_MONITOR_CONNECT
08-01T14:01:12 0 0 0 0 1 0 0.034 monitor.MARIADB_MONITOR_DML
08-01T14:01:12 0 0 0 0 1 0 0.034 monitor.MARIADB_MONITOR_SINGLE
08-01T14:01:12 0 0 0 0 1 0 0.035 monitor.MARIADB_MS_SINGLE
08-01T14:01:12 0 0 0 0 1 0 0.036 monitor.MARIADB_TRAFFIC_STATISTICS
08-01T14:01:12 0 0 2 0 1 0 0.045 monitor.MARIADB_TYPE

检查主从

通过DSN连接从库,首先在主库中创建相关的表和数据库。

create database percona;
CREATE TABLE `percona`.`dsns` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parent_id` int(11) DEFAULT NULL,
`dsn` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
);

插入可以连接从库的用户名、密码、端口等信息

use percona;
insert into dsns(dsn) values('h=192.168.20.,P=3306,u=repl,p=123');

DSNs记录 dsn 列格式如 ​​h=REPLICA_HOST,u=repl_user,p=repl_pass​

检查命令如下:显示所有检查信息,可以通过指定​​--replicate-check-only​​来只显示数据不一致的表信息。

[root@BigData ~]# pt-table-checksum h=192.168.20.5,u=root,p=Sanshi_408,P=3306 --databases=monitor --recursion-method dsn=h=192.168.20.6,D=percona,t=dsns --no-check-binlog-format
Checking if all tables can be checksummed ...
Starting checksum ...
Replica 18c-dg is stopped. Waiting. ---slave进程关闭,无法检查。需要手动启动。
Replica 18c-dg is stopped. Waiting.
Replica 18c-dg is stopped. Waiting.
Replica 18c-dg is stopped. Waiting.
Replica 18c-dg is stopped. Waiting.
Replica 18c-dg is stopped. Waiting.
TS ERRORS DIFFS ROWS DIFF_ROWS CHUNKS SKIPPED TIME TABLE
08-01T14:19:40 0 0 8 0 1 0 178.474 monitor.B_HOST
08-01T14:19:41 0 0 23 0 1 0 1.148 monitor.B_MONITOR_ITEM
08-01T14:19:41 0 0 7 0 1 0 0.185 monitor.B_SEND_MAIL
08-01T14:19:41 0 0 1 0 1 0 0.105 monitor.B_SEND_MAIL_FREQ
08-01T14:19:41 0 0 7 0 1 0 0.082 monitor.B_TRIGGER_RULE
08-01T14:19:41 0 0 14 0 1 0 0.053 monitor.B_WARN_CONFIG
08-01T14:19:41 0 0 46 0 1 0 0.081 monitor.B_WARN_INFO
08-01T14:19:41 0 0 14 0 1 0 0.060 monitor.B_WARN_ITEM
08-01T14:19:41 0 0 3 0 1 0 0.058 monitor.B_WARN_LEVEL
08-01T14:19:41 0 0 1 0 1 0 0.055 monitor.B_WARN_NOTICE
08-01T14:19:42 0 0 0 0 1 0 0.062 monitor.DATA_GROUP
08-01T14:19:42 0 0 0 0 1 0 0.083 monitor.DATA_GROUP_HOST
08-01T14:19:42 0 0 8 0 1 0 0.044 monitor.DB_GROUP
08-01T14:19:42 0 0 17 0 1 0 0.051 monitor.DB_VERSIONS
08-01T14:19:42 0 0 0 0 1 0 0.060 monitor.FLASH_INFO
08-01T14:19:42 0 0 0 0 1 0 0.056 monitor.FLASH_MONITOR
08-01T14:19:42 0 0 0 0 1 0 0.048 monitor.IBCONF
08-01T14:19:42 0 0 1 0 1 0 0.056 monitor.LICENSE
08-01T14:19:42 0 0 0 0 1 0 0.061 monitor.MARIADB_CONFIG
08-01T14:19:42 0 0 0 0 1 0 0.047 monitor.MARIADB_CONFIG_TYPE
08-01T14:19:42 0 0 0 0 1 0 0.069 monitor.MARIADB_MONITOR_CONNECT
08-01T14:19:42 0 0 0 0 1 0 0.061 monitor.MARIADB_MONITOR_DML
08-01T14:19:42 0 0 0 0 1 0 0.043 monitor.MARIADB_MONITOR_SINGLE
08-01T14:19:42 0 0 0 0 1 0 0.045 monitor.MARIADB_MS_SINGLE
08-01T14:19:42 0 0 0 0 1 0 0.042 monitor.MARIADB_TRAFFIC_STATISTICS
08-01T14:19:42 0 0 2 0 1 0 0.041 monitor.MARIADB_TYP
...

列名说明:

  • ​TS​​:时间戳
  • ​ERRORS​​:错误、警告数量
  • ​DIFFS​​​:主从不同的chunk数量。如果指定了​​--no-replicate-check​​​那么该列永远为0.如果指定了​​--replicate-check-only​​,那么只显示数据不一致的表。
  • ​ROWS​​:表的行数
  • ​CHUNKS​​:表分拆分成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​​:表名

默认情况下,会创建一个​​percona.checksums​​​表用于存储检查信息。除了可以通过查看输出信息来验证表的数据同步情况下,也可以通过查询​​percona.checksums​​中数据来查看,如下:

SELECT db, tbl, SUM(this_cnt) AS total_rows, COUNT(*) AS chunks
FROM percona.checksums
WHERE (
master_cnt <> this_cnt
OR master_crc <> this_crc
OR ISNULL(master_crc) <> ISNULL(this_crc))
GROUP BY db, tbl;