pt-table-checksum和pt-table-sync使用

数据库版本:5.6.25

pt工具版本:2.2.14

主从关系一:不同机器同一端口

10.10.228.163:4306(rescs5)

10.9.33.154     :  4306   rescs6)

主从关系二:同一机器不同端口

10.10.228.163:3306(rescs5)

10.10.228.163 :  3307   rescs5)

pt-table-checksum原理

1)、单行数据checksum值的计算

Pt工具先检查表的结构,并且获取表中每一列的数据类型,把所有数据类型都转化为字符串,然后使用concat_ws()函数进行连接,然后使用crc32计算出该行的checksum值。

2)、数据块checksum值的计算

如果一行一行去计算checksum值,再去和从库比较,效率会很低。pt-table-checksum可以利用表中的索引,将表的数据split成一个个chunk,计算的时候也是以chunk为单位。pt-table-checksum引入了聚合函数BIT_XOR()。它的功能可以理解为将这个chunk内的所有行数据拼接起来,再计算CRC32的值,就得到了这个chunk的checksum值。

3)、pt-table-checksum通过在主服务器上执行检查语句,在线检查MySQL复制的一致性,生成replace语句,然后传递到从服务器,再通过update更新master_src的值。通过检测从服务器的this_src和master_src的值从而判断复制是否一致。

为了方便测试,在主库上执行添加用户操作

grant all on *.* to 'ptuser'@'%' identified by 'ptuser';

1)、主从在不同机器同一端口下,在主库上执行

pt-table-checksum --recursion-method="processlist" --nocheck-binlog-format --nocheck-replication-filters --replicate=test.checksums --databases=bukexuetang  h=10.10.228.163,u=ptuser,p=ptuser,P=4306

pt-table-checksum和pt-table-sync使用-LMLPHP

在从库上删除几条记录

delete from activity where id > 100 and id < 120;

再次运行pt-table-checksum

pt-table-checksum --recursion-method="processlist" --nocheck-binlog-format --nocheck-replication-filters --replicate=test.checksums --databases=bukexuetang h=10.10.228.163,u=ptuser,p=ptuser,P=4306

pt-table-checksum和pt-table-sync使用-LMLPHP

通过DIFFS是1就可以看出主从的表数据不一致。怎么不一致呢? 通过指定–replicate=test.checksums参数,就说明把检查信息都写到了checksums表中

pt-table-checksum和pt-table-sync使用-LMLPHP

2)、主从在同一机器不同端口下,在主库上执行

create database percona;
use percona;
CREATE TABLE `slave` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parent_id` int(11) DEFAULT NULL,
`dsn` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert into slave(`id`,`dsn`) values(1,'h=10.10.228.163,P=3307');

pt-table-checksum --recursion-method=dsn=D=percona,t=slave --nocheck-binlog-format --nocheck-replication-filters --replicate=test.checksums --databases=bukexuetang h=10.10.228.163,u=ptuser,p=ptuser,P=3306

pt-table-checksum和pt-table-sync使用-LMLPHP

在从库上删除几条记录

delete from activity where id > 100 and id < 120;

再次运行pt-table-checksum

pt-table-checksum --recursion-method=dsn=D=percona,t=slave --nocheck-binlog-format --nocheck-replication-filters --replicate=test.checksums --databases=bukexuetang h=10.10.228.163,u=ptuser,p=ptuser,P=3306

pt-table-checksum和pt-table-sync使用-LMLPHP

命令参数解释:

--nocheck-replication-filters : 不检查复制过滤规则(replicate-ignore-db、replicate-wild-do-table)。另外需要特别注意执行checksum所在的数据库必须是同步的数据库;

--nocheck-binlog-format:不检查复制的binlog模式。如果binlog模式为ROW,则需要启用—no-check-binlog-format,否则会报错;

--databases=bukexuetang:指定要checksum的数据库;

--replicate=test.checksums:存放checksum结果的表;

--recursion-method : 用来决定查找slave的方式是show full processlist还是show slave hosts还是命令行直接指定还是压根就不准备找从库。如果主库从库使用的是相同端口,那么--recursion-method默认值为processlist,如果主库从库使用了非默认端口,建议通过dsn指定从库信息。dsn即DATA SOURCE NAME,数据源名称;

pt-table-sync原理

用来修复多个实例之间数据的不一致,它可以让主从的数据修复到最终一致。

1)、单行数据checksum值的计算

和pt-table-checksum一样,也是先检查表结构,并获取每一列的数据类型,把所有数据类型都转化为字符串,然后用concat_ws()函数进行连接,由此计算出该行的checksum值。Checksum默认采用crc32计算。

2)、数据块checksum值的计算

和pt-table-checksum工具一样,pt-table-sync会将表的数据split成若干个chunk,计算的时候以chunk为单位。可以理解为将chunk内的所有行的数据拼接起来,再计算crc32的值,既可以得到该chunk的checksum值。

3)、数据修复

pt-table-sync与pt-table-checksum的算法和原理是一样的。再往下,就开始有所不同了:pt-table-checksum只是校验,它把checksum结果存储到统计表,然后把执行过的sql语句记录到binlog,任务就算完成。语句级的复制把计算

逻辑传递到从库,并且在从库执行相同的计算。pt-table-sync则不同,它首先要完成chunk的checksum值计算,一旦发现主从上相同的chunk的checksum值不一样,就会深入到该chunk内部,逐行比较并且修复有问题的行。

它的计算逻辑描述如下:
1)、对每一个从库,每一个表,循环进行如下校验和修复过程。
2)、对每一个chunk,校验时加上for update锁。一旦获得锁,就记录下当前主库的show master status值。
3)、在从库上执行select master_pos_wait()函数,等待从库的sql线程执行到show master status得到位置。以此保证,主从上关于这个chunk的内容不再改变。【select master_pos_wait('master_log_file','master_log_pos');该函数会阻塞直到从服务器达到指定的日志文件和偏移量。此时从服务器和主服务器就同步了,语句返回值为0】.
4)、对这个chunk执行checksum计算,然后与主库的checksum进行比较。
5)、如果checksum相同,说明主从数据一致,接着就可以继续下一个chunk。
6)、如果checksum值不同,说明该chunk有不一致。就会深入到chunk内部,逐行计算checksum并比较(单行checksum的比较过程与chunk的比较过程一样,单行实际是chunk的size等于1的特例)。
7)、如果发现某行不一致,则标记下来。继续检测剩余行,直到这个chunk结束。
8)、对找到的主从不一致的行,采用replace into语句,在主库上执行一遍以生成该行全量的binlog, 并同步到从库,这就会以主库数据为基准来修复从库;对于主库有的,而从库没有的行,采用replace into在主库上插入(注意,不能是insert。这分为两种情况:一是有唯一性主键,如果有唯一性主键或者索引,则insert相同记录会在主库上插入失败;二是没有唯一性主键或者索引,insert相同记录会造成记录重复。故要求pt-table-sync的表必须要有唯一性主键或者索引)。
9)、直到修复该chunk所有不一致的行。继续检查和修复下一个chunk。
10)、直到这个从库上的所有表修复结束。接着继续修复下一个从库。

注意事项:

1)pt-table-checksum工具检查的表可以没有主键或者唯一索引。

2)pt-table-sync工具修复表的时候,表必须有主键或者唯一索引。

3)两个工具在运行的过程中,都会产生对于chunk行块的写锁和一定的负载。所以大家尽量采用脚本的方式在业务低峰期进行。

在从库上删除几条记录
delete from ability_info where id < 120;

从库执行,将不一致的数据打印出来

pt-table-sync --print --sync-to-master h=10.9.33.154,u=ptuser,p=ptuser,P=4306,D=bukexuetang,t=ability_info --charset=utf8

pt-table-checksum和pt-table-sync使用-LMLPHP

pt-table-sync --print --sync-to-master h=10.10.228.163,u=ptuser,p=ptuser,P=3307,D=bukexuetang,t=activity --charset=utf8

pt-table-checksum和pt-table-sync使用-LMLPHP

从库执行,修复不一致的数据

pt-table-sync --execute --sync-to-master h=10.9.33.154,u=ptuser,p=ptuser,P=4306,D=bukexuetang,t=ability_info --charset=utf8

pt-table-sync --execute --sync-to-master h=10.10.228.163,u=ptuser,p=ptuser,P=3307,D=bukexuetang,t=activity --charset=utf8

从库执行,将不一致的数据打印出来

pt-table-sync --print --sync-to-master h=10.9.33.154,u=ptuser,p=ptuser,P=4306,D=bukexuetang,t=ability_info --charset=utf8

pt-table-sync --print --sync-to-master h=10.10.228.163,u=ptuser,p=ptuser,P=3307,D=bukexuetang,t=activity --charset=utf8

pt-table-sync --print --sync-to-master h=10.9.33.154,u=ptuser,p=ptuser,P=4306 --databases bukexuetang --charset=utf8

pt-table-sync --print --sync-to-master h=10.10.228.163,u=ptuser,p=ptuser,P=3307 --databases bukexuetang --charset=utf8

命令参数解释:

--databases : 指定执行同步的数据库,多个用逗号隔开。

--tables : 指定执行同步的表,多个用逗号隔开。

--sync-to-master : 指定一个DSN,即从的IP,他会通过show processlist或show slave status 去自动的找主。

--print : 打印,但不执行命令。

--execute : 执行命令。

--charset : 指定字符集

注意事项:

pt-table-sync后面接的h=xxx.xxx.xxx.xxx是从库的IP和端口,并不是主库

一定要显式指定字符集--charset=utf8

坑的地方,校验完后客户端字符集被设置成了latin1

pt-table-checksum和pt-table-sync使用-LMLPHP

pt-table-checksum和pt-table-sync使用-LMLPHP

显式设置客户端字符集set names utf8;

pt-table-checksum和pt-table-sync使用-LMLPHP

pt-table-checksum和pt-table-sync使用-LMLPHP

05-26 14:42