找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1561

积分

0

好友

231

主题
发表于 12 小时前 | 查看: 2| 回复: 0

pt-table-checksumPercona 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 选项尝试不同的发现方法,例如 hostscluster。如果所有自动发现方法均失败,则可以使用 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 选项即可禁用该检查。需要注意的是,工具提示“可能破坏复制”的说法具有一定误导性,其实际风险在于链式复制下的校验和结果不准确。

无法将会话 binlog_format 切换为 STATEMENT

Failed to /*!50108 SET @@binlog_format := ‘STATEMENT’*/: ...
This tool requires binlog_format=STATEMENT...

当目标环境不支持或禁止切换为 STATEMENT 模式时会出现此错误,常见于以下场景:

  1. Percona XtraDB Cluster (PXC)pxc_strict_mode = ENFORCING 模式下禁止切换。
  2. Amazon RDS/Aurora: 缺少 SUPER 权限,禁止用户修改会话级 binlog_format

解决方案

  • 对于 PXC:可临时将 pxc_strict_mode 设置为 PERMISSIVE(请注意潜在风险):
    SET GLOBAL pxc_strict_mode='PERMISSIVE';
  • 对于 Aurora:如果使用了跨集群或到外部 MySQL 的异步复制,必须在参数组中将 binlog_format 全局设置为 STATEMENT

分块过大或缺少合适索引

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)来工作,以避免对大表进行单次大查询导致负载过高或复制延迟。这要求表上必须有合适的索引(最好是主键或唯一键)用于分块。

解决方案

  1. 确保表结构:为需要校验的表添加主键或唯一索引,这是最根本的解决方案。
  2. 处理统计信息问题:表被跳过常常是因为主从表统计信息不一致或过时。可以尝试:
    • 在校验前对问题表执行 ANALYZE TABLE
    • 考虑在运行校验期间关闭 innodb_stats_on_metadata,以避免统计信息被频繁更新。
    • 若使用 Percona Server for MySQL,可考虑临时禁用 innodb_stats_auto_update
  3. 调整工具参数:适当增加 --chunk-size-limit(默认2)或 --chunk-time 的值,允许工具处理更大的数据块。建议在业务低峰期测试调整。
  4. 重试机制:可以编写脚本,解析工具运行日志,针对被跳过的表进行单独的重试。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-dbreplicate-ignore-table 等复制过滤规则导致的。

解决方案: 使用 --ignore-databases--ignore-tables 选项,让 pt-table-checksum 在计算时也忽略这些表,使其与实际的复制过滤规则保持一致。否则,工具会一直等待从库执行永远不会到达的校验和查询,从而卡在“Waiting to check replicas for differences”的状态。

总结

pt-table-checksum 是验证 MySQL主从复制 数据一致性的强大工具。成功使用它有时需要一些技巧,包括正确使用工具参数、理解其工作原理,以及在数据库设计阶段就为表规划合适的主键。一个良好的主键不仅能让 pt-table-checksum 运行得更高效,有时甚至是其正常工作的必要条件。通过理解上述常见错误及其解决方案,可以更顺畅地利用该工具保障数据一致性。




上一篇:机器学习入门实战:基于Scikit-learn的12周免费课程与项目指南
下一篇:JavaFX桌面开发实战:从C++/Qt迁移构建现代化物联网测试工具
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-24 17:20 , Processed in 0.252671 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表