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
在从库上删除几条记录
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
通过DIFFS是1就可以看出主从的表数据不一致。怎么不一致呢? 通过指定–replicate=test.checksums参数,就说明把检查信息都写到了checksums表中
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
在从库上删除几条记录
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
命令参数解释:
--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-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 --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
显式设置客户端字符集set names utf8;