pt-table-syn 用来修复主从数据一致, 可以做单向和双向同步的表数据。他可以同步单个表,也可以同步整个库。它不同步表结构、索引、或任何其他模式对象。所以在修复一致性之前需要保证表存在。
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)、直到这个从库上的所有表修复结束。接着继续修复下一个从库。
pt-table-sync使用(在从库执行):
1)、主从库上增加相应的用户,用于给从库数据修复使用
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE,DROP,SUPER,PROCESS ON *.* TO 'checkdata'@'xxx IDENTIFIED BY 'xxx'
2)、pt-table-sync打印出来
pt-table-sync --sync-to-master h=xxxx,u=checkdata,p=checkdata8s,P=6301 --databases=ymore --charset=utf8mb4 –print
3)、pt-table-sync修复数据
pt-table-sync --sync-to-master h=xxxx,u=checkdata,p=checkdata8s,P=6301 --databases=ymore --charset=utf8mb4 --print --execute