当前位置: 首页 > 工具软件 > MySQL-Sync > 使用案例 >

MySQL5.7使用pt-table-sync修复不一致性数据

郤仰岳
2023-12-01

接上篇:MySQL5.7使用pt-table-checksum 检查主从数据一致性


通过pt-table-checksum发现主从数据不一致的话,可以通过pt-table-sync来同步数据。


原理说明:

总是在主上执行数据的更改,再同步到从上,不会直接更改成 从的数据,在主上执行更改是基于主上现在的数据,不会更改主上的数据。注意使用之前先备份你的数据,避免造成数据的丢失. 执行 execute 之前最好先换成--print 或--dry-run 查看一下会变更哪些数据。

参数说明:

参数
说明
--replicate
指定通过pt-table-checksum得到的表,这2个工具差不多都会一直用。
--databases
指定执行同步的数据库,多个用逗号隔开。
--tables
指定执行同步的表,多个用逗号隔开。
--sync-to-master
指定一个DSN,即从的IP,他会通过show processlist或show slave status 去自动的找主。
h=127.0.0.1
服务器地址,命令里有2个ip,第一次出现的是M的地址,第2次是Slave的地址。
u=root
帐号。
p=123456 
密码。
--print 
打印,但不执行命令。
--execute
执行命令。

对找到的主从不一致的行,采用replace into语句,在主库执行一遍以生成该行全量的binlog,并同步到从库,这会以主库数据为基准来修复从库;

对于主库有的行而从库没有的行,采用replace在主库上插入(必须不能是insert);

对于从库有而主库没有的行,通过在主库执行delete来删除(pt-table-sync强烈建议所有的数据修复都只在主库进行,而不建议直接修改从库数据;但是也有特例,后面会讲到)。


先试着运行一下,--print参数只是打印结果,不执行命令:

[root@qht131 ~]# pt-table-sync h=172.17.61.131,u=repl,p=repl,P=3306 --databases=l5m --tables=t2 --replicate=percona.checksums --print
Failed to /*!50108 SET @@binlog_format := 'STATEMENT'*/: DBD::mysql::db do failed: Access denied; you need (at least one of) the SUPER privilege(s) for this operation [for Statement "/*!50108 SET @@binlog_format := 'STATEMENT'*/"] at /usr/local/bin/pt-table-sync line 10863.

This tool requires binlog_format=STATEMENT, but the current binlog_format is set to ROW and an error occurred while attempting to change it.  If running MySQL 5.1.29 or newer, setting binlog_format requires the SUPER privilege.  You will need to manually set binlog_format to 'STATEMENT' before running this tool.
Issuing rollback() due to DESTROY without explicit disconnect() of DBD::mysql::db handle ;host=172.17.61.132;port=3306;mysql_read_default_group=client at /usr/local/bin/pt-table-sync line 10866.
Issuing rollback() due to DESTROY without explicit disconnect() of DBD::mysql::db handle ;host=172.17.61.131;port=3306;mysql_read_default_group=client at /usr/local/bin/pt-table-sync line 10866.
Issuing rollback() due to DESTROY without explicit disconnect() of DBD::mysql::db handle ;host=172.17.61.131;port=3306;mysql_read_default_group=client at /usr/local/bin/pt-table-sync line 10866.

遇到这个错误的解决办法是在slave上增加相应的权限:

slave server:

mysql>  grant select,create,drop,insert,delete,update,alter on percona.* to repl@'172.17.61.%';
Query OK, 0 rows affected (0.00 sec)

mysql> grant SELECT,LOCK TABLES,PROCESS,SUPER on *.* to  repl@'172.17.61.%';
Query OK, 0 rows affected (0.00 sec)

mysql>  flush privileges;
Query OK, 0 rows affected (0.00 sec)

在主库上再试一次:

[root@qht131 ~]# pt-table-sync h=172.17.61.131,u=repl,p=repl,P=3306 --databases=l5m --tables=t2 --replicate=percona.checksums --print
DELETE FROM `l5m`.`t2` WHERE `c4`='34' LIMIT 1 /*percona-toolkit src_db:l5m src_tbl:t2 src_dsn:P=3306,h=172.17.61.131,p=...,u=repl dst_db:l5m dst_tbl:t2 dst_dsn:P=3306,h=172.17.61.132,p=...,u=repl lock:1 transaction:1 changing_src:percona.checksums replicate:percona.checksums bidirectional:0 pid:2955 user:root host:qht131*/;

由于从库只是比主库多了一条数据,pt-table-sync将以主库以准,在主库执行一个删除操作的事件,然后slave应用此事件完成同步。

不过是真正执行的时候遇到了下面的错误:

[root@qht131 ~]# pt-table-sync h=172.17.61.131,u=repl,p=repl,P=3306 --databases=l5m --tables=t2 --replicate=percona.checksums --execute
DELETE command denied to user 'repl'@'qht131' for table 't2' [for Statement "DELETE FROM `l5m`.`t2` WHERE `c4`='34' LIMIT 1 /*percona-toolkit src_db:l5m src_tbl:t2 src_dsn:P=3306,h=172.17.61.131,p=...,u=repl dst_db:l5m dst_tbl:t2 dst_dsn:P=3306,h=172.17.61.132,p=...,u=repl lock:1 transaction:1 changing_src:percona.checksums replicate:percona.checksums bidirectional:0 pid:3035 user:root host:qht131*/"] at line 10744 while doing l5m.t2 on 172.17.61.132

由于repl没有delete权限造成的,在主从都赋予一下权限:

mysql>  grant select,create,drop,insert,delete,update,alter on *.* to repl@'172.17.61.%';
Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

再次执行一次没有问题了

[root@qht131 ~]# pt-table-sync h=172.17.61.131,u=repl,p=repl,P=3306 --databases=l5m --tables=t2 --replicate=percona.checksums --execute

检查slave库的数据,这时不一致的数据已被删除。

mysql> select * from l5m.t2;
+------+------+------+----+
| c1   | c2   | c3   | c4 |
+------+------+------+----+
|    1 | abc  |   22 | 33 |
+------+------+------+----+
1 row in set (0.00 sec)

需要注意的是,需要同步的表上必须要有主键或者唯一索引,否则会出错。


对pt-table-checksum和pt-table-sync这一组工具进行了最简单的测试,其实运行这一组命令不一定需要在主从结构的主库上进行,网段内的任何电脑都可以运行,前提就是安装好这套工具就好。另外在pt-table-checksum中没有指定--recursion-method,这时工具会从show processlist中在主库中自动寻找从库,当然也可以使用Host以及dsn的方式来连接主从库,我没有对这两种方法进行测试。



 类似资料: