pt-table-checksum是一个很好用的用来检查mysql数据库中主服务器和备服务器数据是否一致的好工具,通常可以在主服务器上面运行下面的语句:
上面this_cns=1000的数据记录区有数据是不同步的,我们在从库上执行:
sleect * from checksums\G;找到this_cnt等于1000的值
看到了吗?this_crc的值与master_crc的值是不相等的,说明在主键为1到1374这个区域有数据是不同的,给我们上面指定的id为1300的数据完全符合。
执行如下的语句:
test.checksums就是我们通过pt-table-checksums得到的表,前面的h,u,p是主库的信息,后面是备库的信息,--print是把要修改的sql语句打印出来。
然后在备库的user表中执行REPLACE INTO `test`.`user`(`id`, `name`) VALUES ('1300', '123123'),就把备库的数据和主库一致了。
pt-table-checksum --replicate = test.checksums <master_host>
通过上述语句可以很好的检查主备的数据是否一致。该命令的原理就是检查指定需要检查的库或者表,并且把结果放到test.checksums中。然后当从库执行完毕的时候,就可以比较主库与从库的不同了。
在我的服务器上主库的地址是192.168.1.106,备库上是192.168.1.104,现在已经主从同步成功。表中一共有2560跳记录,我们假设让其中id为1300的记录不同。
现在在主库上指向pt-table-checksum命令,对于如何安装这个命令,其中有篇文章已经专门介绍过了。执行如下命令:
/usr/local/bin/pt-table-checksum --replicate=test.checksums --no-check- binlog-format --databases=test h=192.168.1.106,u=mysql,p=123456
注意:要让上述命令生效,必须要确保从库已经连接到主库,并且从库的io和sql线程都为yes。其中--replicate就是要把数据插入到的表中,--no-check-binlog-format不对binlog的格式进行检查,--databases=就是要对那个数据库进行检查,当然也可以用--tables对其具体的表进行检查,h是主服务器的地址,u是同步的账号,p是同步的密码
执行完成以后可以看到在user表中diffs的值为1,表明这个表中有数据是不同步。然后切换到从库,也就是192.168.1.104的这台机子上执行如下的sql语句:
SELECT db, tbl, SUM(this_cnt) AS total_rows, COUNT(*) AS chunks FROM test.checksums WHERE ( master_cnt <> this_cnt OR master_crc <> this_crc OR ISNULL(master_crc) <> ISNULL(this_crc)) GROUP BY db, tbl;
会出来下面的结果:
+------+------+------------+--------+
| db | tbl | total_rows | chunks |
+------+------+------------+--------+
| test | user | 1000 | 1 |
+------+------+------------+--------+
上面this_cns=1000的数据记录区有数据是不同步的,我们在从库上执行:
sleect * from checksums\G;找到this_cnt等于1000的值
*************************** 2. row ***************************
db: test
tbl: user
chunk: 1
chunk_time: 0.065049
chunk_index: PRIMARY
lower_boundary: 1
upper_boundary: 1374
this_crc: ab2b7998
this_cnt: 1000
master_crc: e438fc61
master_cnt: 1000
ts: 2013-08-18 19:27:31
看到了吗?this_crc的值与master_crc的值是不相等的,说明在主键为1到1374这个区域有数据是不同的,给我们上面指定的id为1300的数据完全符合。
下面来看下如何通过pt-table-sync修复主备数据的不一致
主库上id为1300的数据为备库上id为1300的数据为
执行如下的语句:
/usr/local/bin/pt-table-sync --replicate=test.checksums h=192.168.1.106,u=mysql,p='123456' h=192.168.1.104,u=mysql,p='123456' --print
REPLACE INTO `test`.`user`(`id`, `name`) VALUES ('1300', '123123') /*percona-toolkit src_db:test src_tbl:user src_dsn:h=192.168.1.106,p=...,u=mysql dst_db:test dst_tbl:user dst_dsn:h=192.168.1.104,p=...,u=mysql lock:1 transaction:1 changing_src:test.checksums replicate:test.checksums bidirectional:0 pid:1655 user:root host:slave*/;
test.checksums就是我们通过pt-table-checksums得到的表,前面的h,u,p是主库的信息,后面是备库的信息,--print是把要修改的sql语句打印出来。
然后在备库的user表中执行REPLACE INTO `test`.`user`(`id`, `name`) VALUES ('1300', '123123'),就把备库的数据和主库一致了。