主从数据校验使用percona-toolkit工具集的以下两个工具(主库上使用):
pt-table-checksum #检查主从数据是否一致,
pt-table-sync #把主库数据同步到从库
适用场景如下:
1). 数据迁移前后进行数据一致性检查
2). 当主从复制出现报错中断或者主从数据出现不一致时,对主从数据进行一致性检查并进行修复
3). 在从库上执行了误操作
4). 定期进行校验(如每个月对复制环境进行校验以确定复制是一致的)
原理:
pt-table-checksum在主库上利用SBR格式对一段数据做hashcode函数运算,然后复制到从库上去检查,对比这个hashcode结果是否一样。
常用参数:
--nocheck-replication-filters :不检查复制过滤器,建议启用。后面可以用--databases来指定需要检查的数据库。
--no-check-binlog-format : 不检查复制的binlog模式,要是binlog模式是ROW,则会报错。
--replicate-check-only :只显示不同步的信息。
--replicate=s:把checksum的信息写入到指定表中,建议直接写到被检查的数据库当中。
--databases :指定需要被检查的数据库,多个则用逗号隔开。
--tables :指定需要被检查的表,多个用逗号隔开
--host=s,h=127.0.0.1 :Master的地址
--user=s,u=root :用户名
--password=s,p=123456:密码
--port=i,P=3306 :端口
--recursion-method=a #发现从库的参数,建议用processlist
METHOD USES
=========== =============================================
processlist SHOW PROCESSLIST
hosts SHOW SLAVE HOSTS
cluster SHOW STATUS LIKE 'wsrep\_incoming\_addresses'
dsn=DSN DSNs from a table
none Do not find slaves
注意:
用于执行pt-table-checksum命令的用户必须要有super权限,以可以修改一些变量信息(如:binlog_format变量在执行这个命令时要修改为statement格式,如果使用了row格式,则使用参数--no-check-binlog-format 不检查row格式),另外还要注意:使用这两个工具前提是表必须有主键
示例:
环境,已经搭建好传统复制的主从环境:
192.168.0.32 主库
192.168.0.72 从库
1. 在主从库都授权一个帐号:
mysql > GRANT SELECT, PROCESS, SUPER, REPLICATION SLAVE ON *.* TO 'checksums'@'192.168.0.%' IDENTIFIED BY 'xxx';
mysql > flush privileges;
2. 在主库建库建表:
mysql > create database xiaoboluo;
mysql > CREATE TABLE `aa` (
`aa` varchar(1) DEFAULT '',
`bb` varchar(1) DEFAULT NULL,
`id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
3. 主库插入测试数据:
mysql > INSERT INTO `aa` VALUES ('1','1',1),('2','2',2),('5','2',5);
4. 在从库检查库、表和数据是否有同步完成,确认无误后开始下面的步骤:
在从库上把id=1的行删掉,插入一行数据,再把id=5的行修改一下:
mysql > delete from xiaoboluo.aa where id=1;
mysql > insert into xiaoboluo.aa values('4','4',4);
mysql > update xiaoboluo.aa set bb=5 where id=5;
5. 到主库执行pt-table-checksum命令:
shell > pt-table-checksum --nocheck-replication-filters --no-check-binlog-format --replicate=xiaoboluo.checksums --create-replicate-table --databases=xiaoboluo -h 192.168.0.38 -P 3306 -u root -pxxx --recursion-method="processlist"
最重要的是看diffs这一列(发现表aa主从数据不一致)
TS ERRORS DIFFS ROWS CHUNKS SKIPPED TIME TABLE
12-24T12:17:58 0 1 3 1 0 0.010 xiaoboluo.aa
执行结果显示参数意义:
TS :完成检查的时间。
ERRORS :检查时候发生错误和警告的数量。
DIFFS :0表示一致,大于0表示不致。当指定--no-replicate-check时,会一直为0,当指定--replicate-check-only会显示不同的信息。
ROWS :表的行数。
CHUNKS :被划分到表中的块的数目。
SKIPPED :由于错误或警告或过大,则跳过块的数目。
TIME :执行的时间。
TABLE :被检查的表名。
6. 接着执行pt-table-sync命令进行数据同步,同步之前最好先使用该命令的--print命令打印一下看看有些什么数据不一致:
shell > pt-table-sync --replicate=xiaoboluo.checksums --databases=xiaoboluo --charset=utf8 h=192.168.0.38,u=root,p=xxx --print
建议先用: --print 打印出来(这里会打印delete什么数据,replace into什么数据,pt-table-checksum在检测主库有数据,而从库没有的数据的时候,不会显示出来,所以最好这里print一下就可以看到主库多出来的数据),类似如下:
DELETE FROM `xiaoboluo`.`aa` WHERE `id`='4' LIMIT 1 /*percona-toolkit src_db:xiaoboluo src_tbl:aa src_dsn:A=utf8,h=192.168.0.38,p=...,u=root dst_db:xiaoboluo dst_tbl:aa dst_dsn:A=utf8,h=192.168.0.72,p=...,u=root lock:1 transaction:1 changing_src:xiaoboluo.checksums replicate:xiaoboluo.checksums bidirectional:0 pid:29301 user:root host:localhost.localdomain*/;
REPLACE INTO `xiaoboluo`.`aa`(`aa`, `bb`, `id`) VALUES ('1', '1', '1') /*percona-toolkit src_db:xiaoboluo src_tbl:aa src_dsn:A=utf8,h=192.168.0.38,p=...,u=root dst_db:xiaoboluo dst_tbl:aa dst_dsn:A=utf8,h=192.168.0.72,p=...,u=root lock:1 transaction:1 changing_src:xiaoboluo.checksums replicate:xiaoboluo.checksums bidirectional:0 pid:29301 user:root host:localhost.localdomain*/;
REPLACE INTO `xiaoboluo`.`aa`(`aa`, `bb`, `id`) VALUES ('5', '2', '5') /*percona-toolkit src_db:xiaoboluo src_tbl:aa src_dsn:A=utf8,h=192.168.0.38,p=...,u=root dst_db:xiaoboluo dst_tbl:aa dst_dsn:A=utf8,h=192.168.0.72,p=...,u=root lock:1 transaction:1 changing_src:xiaoboluo.checksums replicate:xiaoboluo.checksums bidirectional:0 pid:29301 user:root host:localhost.localdomain*/;
7. 然后在--execute选项执行同步数据:
shell > pt-table-sync --replicate=xiaoboluo.checksums --databases=xiaoboluo --charset=utf8 h=192.168.0.38,u=root,p=xxx --execute
然后在用pt-table-checksum检查下,如果diffs列全部为0则表示主从数据已经一致。
TS ERRORS DIFFS ROWS CHUNKS SKIPPED TIME TABLE
12-24T12:22:31 0 0 3 1 0 0.271 xiaoboluo.aa
该工具对于从库上多的数据,会在主库上发起delete操作,对于从库上少的数据或者是主从数据中主键一样,但是其他列数据不一样的数据,会在主库上发起replace into操作。注意:都是在主库上操作,从库不操作。那么怎么知道主从数据谁多谁少呢,依据就是checksums表中的校验信息。
pt-table-sync也是使用statement格式记录操作过程中的二进制日志的,操作过程中最好把主从的general_log都打开。这样就能知道在修复过程中,主从库到底做了些什么操作。