pt-table-checksum 是 Percona Toolkit 中最常用的工具之一,主要用于识别主从服务器之间的数据差异。因此,我们经常会收到关于该工具运行中产生的各类错误和警告的咨询。本文将梳理 pt-table-checksum 最常见的几类问题,并提供相应的解决思路,帮助用户高效处理这些警告或错误。
无法检测到从库 (Cannot detect slaves)
Cannot connect to h=127.0.0.1,p=...,u=percona
Diffs cannot be detected because no slaves were found. Please read the --recursion-method documentation for information.
此错误表明工具无法连接到从库。默认情况下,pt-table-checksum 通过检查主库的 PROCESSLIST 来发现从库线程,进而定位从库。如果从库运行在不同的端口、主机名解析不正确、主从位于同一主机,或在使用基于 Galera 的集群时,这种方法可能会失效。
解决方案: 使用 --recursion-method 选项尝试不同的发现方法,例如 hosts 或 cluster。如果所有自动发现方法均失败,则可以使用 dsn 方法手动指定每个从库的连接信息。
以下是在集群环境下使用 cluster 方法的示例:
# pt-table-checksum --user=root --password=*** --databases="db1" --recursion-method=cluster 192.168.88.82
Checking if all tables can be checksummed ...
Starting checksum ...
Not checking replica lag on pxc02 because it is a cluster node.
Not checking replica lag on pxc03 because it is a cluster node.
TS ERRORS DIFFS ROWS CHUNKS SKIPPED TIME TABLE
03-03T00:24:13 0 0 12 1 0 0.033 db1.t1
03-03T00:24:13 0 0 4 1 0 0.031 db1.t2
当需要手动指定 DSN(例如对于 MySQL Sandbox 实例)时,需要将从库信息插入到一个特定的表中:
master [localhost] {msandbox} ((none)) > 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)
);
Query OK, 0 rows affected (0.08 sec)
master [localhost] {msandbox} ((none)) > insert into percona.dsns values (null,null,"h=localhost,S=/tmp/mysql_sandbox20997.sock");
Query OK, 1 row affected (0.03 sec)
随后通过 DSN 表指定从库进行检查:
$ pt-table-checksum --databases="test" --tables="s1" --recursion-method=dsn=localhost,D=percona,t=dsns u=root,p=msandbox,h=localhost,S=/tmp/mysql_sandbox20996.sock
Checking if all tables can be checksummed ...
Starting checksum ...
TS ERRORS DIFFS ROWS CHUNKS SKIPPED TIME TABLE
03-19T14:16:05 0 1 0 1 0 0.344 test.s1
从库使用 ROW 格式的二进制日志
Replica slave1.myorg.com has binlog_format ROW which could cause pt-table-checksum to break replication...
此警告的根源在于,pt-table-checksum 需要在 STATEMENT 格式下工作,它会在自己的会话中设置 binlog_format=STATEMENT。然而,此会话设置不会传递到从库自身的二进制日志中。在链式复制拓扑中,第二级及更高级别的从库将无法正确计算差异,因为二进制日志中记录的是数据行变更,而非校验和计算语句。
解决方案: 如果所有从库都直接连接至主库(即非链式复制),此警告可以忽略。使用 --no-check-binlog-format 选项即可禁用该检查。需要注意的是,工具提示“可能破坏复制”的说法具有一定误导性,其实际风险在于链式复制下的校验和结果不准确。
Failed to /*!50108 SET @@binlog_format := ‘STATEMENT’*/: ...
This tool requires binlog_format=STATEMENT...
当目标环境不支持或禁止切换为 STATEMENT 模式时会出现此错误,常见于以下场景:
- Percona XtraDB Cluster (PXC):
pxc_strict_mode = ENFORCING 模式下禁止切换。
- Amazon RDS/Aurora: 缺少
SUPER 权限,禁止用户修改会话级 binlog_format。
解决方案:
分块过大或缺少合适索引
Cannot checksum table db_name.table_name: There is no good index and the table is oversized.
或
Skipping table because on the master it would be checksummed in one chunk but on these replicas it has too many rows...
pt-table-checksum 通过将表拆分为多个数据块(chunk)来工作,以避免对大表进行单次大查询导致负载过高或复制延迟。这要求表上必须有合适的索引(最好是主键或唯一键)用于分块。
解决方案:
- 确保表结构:为需要校验的表添加主键或唯一索引,这是最根本的解决方案。
- 处理统计信息问题:表被跳过常常是因为主从表统计信息不一致或过时。可以尝试:
- 在校验前对问题表执行
ANALYZE TABLE。
- 考虑在运行校验期间关闭
innodb_stats_on_metadata,以避免统计信息被频繁更新。
- 若使用 Percona Server for MySQL,可考虑临时禁用
innodb_stats_auto_update。
- 调整工具参数:适当增加
--chunk-size-limit(默认2)或 --chunk-time 的值,允许工具处理更大的数据块。建议在业务低峰期测试调整。
- 重试机制:可以编写脚本,解析工具运行日志,针对被跳过的表进行单独的重试。
pt-table-checksum 支持对单个表重复运行,新的校验结果会覆盖旧值。
次优查询计划警告
Skipping chunk 1 of db_name.table_name because MySQL used only 3 bytes of the PRIMARY index instead of 9...
此警告源于工具启用了 --check-plan(默认启用)。它会检查 EXPLAIN 输出,如果发现 MySQL 没有使用完整的索引或使用了非预期索引,则会跳过该数据块,以防执行代价高昂的全表扫描。
解决方案: 如果确认该警告不影响校验准确性,且希望工具检查所有数据,可以使用 --no-check-plan 禁用执行计划检查。但需注意,这可能会增加执行全表扫描的风险。
从库上缺失或被过滤的表
Error checksumming table test.dummy: Error getting row count estimate of table test.dummy on replica ... Table ‘test.dummy’ doesn‘t exist
此错误明确表示,主库上存在的表 test.dummy 在从库上不存在。这通常是由于设置了 replicate-ignore-db 或 replicate-ignore-table 等复制过滤规则导致的。
解决方案: 使用 --ignore-databases 或 --ignore-tables 选项,让 pt-table-checksum 在计算时也忽略这些表,使其与实际的复制过滤规则保持一致。否则,工具会一直等待从库执行永远不会到达的校验和查询,从而卡在“Waiting to check replicas for differences”的状态。
总结
pt-table-checksum 是验证 MySQL主从复制 数据一致性的强大工具。成功使用它有时需要一些技巧,包括正确使用工具参数、理解其工作原理,以及在数据库设计阶段就为表规划合适的主键。一个良好的主键不仅能让 pt-table-checksum 运行得更高效,有时甚至是其正常工作的必要条件。通过理解上述常见错误及其解决方案,可以更顺畅地利用该工具保障数据一致性。