数据库版本:5.6.25算法
pt工具版本:2.2.14sql
主从关系一:不一样机器同一端口数据库
10.10.228.163:4306(rescs5)服务器
10.9.33.154 : 4306 rescs6)ide
主从关系二:同一机器不一样端口函数
10.10.228.163:3306(rescs5)工具
10.10.228.163 : 3307 rescs5)测试
pt-table-checksum原理this
1)、单行数据checksum值的计算spa
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;