注意事项
master和slave必须是同步状态
-
master show slave hosts;
-
slave show slave status\G;看看是否同步成功
-
要是表中没有唯一索引或则主键则会报错:
Can't make changes on the master because no unique index exists at /usr/local/bin/pt-table-sync line 10684..
-
/usr/local/bin/pt-table-checksum 使用是不是还有缓存啊,更新了权限,最好再开一个窗口,执行pt命令
安装
yum -y install perl-Time-HiRes or
yum install perl perl-devel perl-Time-HiRes perl-DBI perl-DBD-MySQ
tar xvf percona-toolkit-2.2.18.tar.gz
cd percona-toolkit-2.2.18
perl Makefile.PL
make && make install
使用
pt-table-checksum是在主从基础上操作的
https://www.cnblogs.com/gomysql/p/3662264.html
master
GRANT SELECT, PROCESS, SUPER, REPLICATION SLAVE ON *.* TO 'checksums'@'masterip' IDENTIFIED BY 'MANAGER';
grant all on test.* to 'checksums'@'masterip' IDENTIFIED BY 'MANAGER';
为什么要赋予test权限,因为会生成checksums表,在test数据库中
做完这个操作后,slave会同步过去,slave确实也需要这样的权限。
master
/usr/local/bin/pt-table-checksum h='masterip',u='checksums',p='MANAGER',P=3306 --nocheck-replication-filters --replicate=test.checksums --no-check-binlog-format
检测所有数据库的不同,diff字段是否为1,如果检测单个库,加 -d 参数
slave上可以查询
SELECT db,tbl, SUM(this_cnt) AS total_rows, COUNT(*) AS chunks FROM test.checksums WHERE ( master_cnt <> this_cnt OR master_crc <> this_crc OR ISNULL(master_crc) <> ISNULL(this_crc)) GROUP BY db, tbl;
原理
参考 https://segmentfault.com/a/1190000004309169
为了减少对数据库的干预,pt-table-checksum
还会自动侦测并连接到从库,当然如果失败,可以指定--recursion-method
选项来告诉从库在哪里。它的易用性还体现在,复制若有延迟,在从库 checksum 会暂停直到赶上主库的计算时间点(也通过选项--
设定一个可容忍的延迟最大值,超过这个值也认为不一致)。
为了保证主数据库服务的安全,该工具实现了许多保护措施:
-
自动设置
innodb_lock_wait_timeout
为1s,避免引起 -
默认当数据库有25个以上的并发查询时,
pt-table-checksum
会暂停。可以设置--max-load
选项来设置这个阀值 -
当用 Ctrl+C 停止任务后,工具会正常的完成当前 chunk 检测,下次使用
--resume
选项启动可以恢复继续下一个 chunk
工作过程
1\. 连接到主库:pt工具连接到主库,然后自动发现主库的所有从库。默认采用show full processlist来查找从库,但是这只有在主从实例端口相同的情况下才有效。
3\. 查找主库或者从库是否有复制过滤规则:这是为了安全而默认检查的选项。你可以关闭这个检查,但是这可能导致checksum的sql语句要么不会同步到从库,要么到了从库发现从库没有要被checksum的表,这都会导致从库同步卡库。
5\. 开始获取表,一个个的计算。
6\. 如果是表的第一个chunk,那么chunk-size一般为1000;如果不是表的第一个chunk,那么采用19步中分析出的结果。
7\. 检查表结构,进行数据类型转换等,生成checksum的sql语句。
8\. 根据表上的索引和数据的分布,选择最合适的split表的方法。
9\. 开始checksum表。
10\. 默认在chunk一个表之前,先删除上次这个表相关的计算结果。除非–resume。
14\. 根据explain的结果,判断chunk的size是否超过了你定义的chunk-size的上限。如果超过了,为了不影响线上性能,这个chunk将被忽略。
15\. 把要checksum的行加上for update锁,并计算。
17-18\. 把计算结果存储到master_crc master_count列中。
19\. 调整下一个chunk的大小。
20\. 等待从库追上主库。如果没有延迟备份的从库在运行,最好检查所有的从库,如果发现延迟最大的从库延迟超过max-lag秒,pt工具在这里将暂停。
21\. 如果发现主库的max-load超过某个阈值,pt工具在这里将暂停。
22\. 继续下一个chunk,直到这个table被chunk完毕。
23-24\. 等待从库执行完checksum,便于生成汇总的统计结果。每个表汇总并统计一次。
25-26\. 循环每个表,直到结束。
你需要知道的选项
-
--replicate-check
:执行完 checksum 查询在percona.checksums表中,不一定马上查看结果呀 —— yes则马上比较chunk的crc32值并输出DIFFS列,否则不输出。默认yes,如果指定为--noreplicate-check
,一般后续使用下面的--replicate-check-only
去输出DIFF结果。 -
--replicate-check-only
:不在主从库做 checksum 查询,只在原有percona.checksums
表中查询结果,并输出数据不一致的信息。周期性的检测一致性时可能用到。 -
--nocheck-binlog-format
:不检测日志格式。这个选项对于 ROW 模式的复制很重要,因为pt-table-checksum
会在 Master和Slave 上设置binlog_format=STATEMENT
(确保从库也会执行 checksum SQL),MySQL限制从库是无法设置的,所以假如行复制从库,再作为主库复制出新从库时(A->B->C),B的checksums数据将无法传输。(没验证) -
--replicate=
指定 checksum 计算结果存到哪个库表里,如果没有指定,默认是 percona.checksums 。
但是我们检查使用的mysql用户一般是没有 create table 权限的,所以你可能需要先手动创建:
使用dsn跨数据中心检测
常见错误
-
Diffs cannot be detected because no slaves were found
不能自动找到从库,确认processlist或host或dsns方式用对了。 -
Cannot connect to h=slave1.*.com,p=...,u=percona_user
可以在pt-table-checksum
命令前加PTDEBUG=1
来看详细的执行过程,如端口、用户名、权限错误。 -
Waiting for the --replicate table to replicate to XXX
问题出在 percona.checksums 表在从库不存在,根本原因是没有从主库同步过来,所以看一下从库是否延迟严重。 -
Pausing because Threads_running=25
反复打印出类似上面停止检查的信息。这是因为当前数据库正在运行的线程数大于默认25,pt-table-checksum 为了减少对库的压力暂停检查了。等数据库压力过了就好了,或者也可以直接 Ctrl+C 终端,下一次加上--resume
继续执行,或者加大--max-load=
值。 -
字符集问题
注意事项
1.从库配置表上需要加上,
report_host=slave_ip
report_port=slave_port
不然将报Diffscannot be detected because no slaves were found.错误
2.表中没有索引,pt-table-checksum将没办法处理
3.表中只有普通索引。当数据列有重复并且正好在分块的交界中,将会报错。所以表中最好有一个唯一索引列。
01-07T12:05:29 Error checksumming tablefreedom.a6: Possible infinite loop detected! The lower boundary for chunk 2 is <cc, cc> and the lower boundaryfor chunk 3 is also <cc, cc>. Thisusually happens when using a non-unique single column index. The current chunk index for table freedom.a6is name which is not unique and covers 1 colum
4.块的定义过大。当块大于表的行数时,将会产生全表锁。