【mysql】pt工具之pt-table-sync
时间:2015-09-09 04:09:34 作者:beebol 标签: mysql pt-table-rsync 分类: mysql
pt-table-sync是percona-toolkit工具组中的其中之一,主要功能是解决mysql复制的不一致性问题。参考“【mysql】pt工具之pt-table-checksum”,进行一致性检查。大概原理:基于主上的数据,生成sql执行,同步到从上,主上的数据不会变。可以通过--print 或者--dry-run查看有哪些数据变更,然后再进行execute。
[root@mysql.dmc.com ~]$pt-table-sync --user=checksum --password=checksum h=10.1.16.74,D=test,t=t_order h=10.1.16.76 --printUPDATE `test`.`t_order` SET `customer_id`='6' WHERE `order_id`='6' LIMIT 1 /*percona-toolkit src_db:test src_tbl:t_order src_dsn:D=test,h=10.1.16.74,p=...,t=t_order,u=checksum dst_db:test dst_tbl:t_order dst_dsn:D=test,h=10.1.16.76,p=...,t=t_order,u=checksum lock:0 transaction:1 changing_src:0 replicate:0 bidirectional:0 pid:27004 user:root host:mysql.dmc.com*/; UPDATE `test`.`t_order` SET `customer_id`='6' WHERE `order_id`='6' LIMIT 1 /*percona-toolkit src_db:test src_tbl:t_order src_dsn:D=test,h=10.1.16.74,p=...,t=t_order,u=checksum dst_db:test dst_tbl:t_order dst_dsn:D=test,h=10.1.16.76,p=...,t=t_order,u=checksum lock:0 transaction:1 changing_src:0 replicate:0 bidirectional:0 pid:27004 user:root host:mysql.dmc.com*/;
如上是将test库中的t_order表变更语句打印出来了。
[root@mysql.dmc.com ~]$pt-table-sync --user=checksum --password=checksum h=10.1.16.74,D=test,t=t_order h=10.1.16.76 --execute
如上是进行数据一致性同步
[root@mysql.dmc.com ~]$pt-table-sync --user=checksum --password=checksum h=10.1.16.74 h=10.1.16.76 --replicate percona.checksums --print
根据checksum显示出所有不一致的数据变更
[root@mysql.dmc.com ~]$pt-table-sync --user=checksum --password=checksum h=10.1.16.74 h=10.1.16.76 --replicate percona.checksums --print --databases test REPLACE INTO `test`.`t_order`(`order_id`, `customer_id`) VALUES ('6', '6') /*percona-toolkit src_db:test src_tbl:t_order src_dsn:h=10.1.16.74,p=...,u=checksum dst_db:test dst_tbl:t_order dst_dsn:h=slave_16.76,p=...,u=checksum lock:1 transaction:1 changing_src:percona.checksums replicate:percona.checksums bidirectional:0 pid:27194 user:root host:mysql.dmc.com*/;[root@mysql.dmc.com ~]$pt-table-sync --user=checksum --password=checksum h=10.1.16.74 h=10.1.16.76 --replicate percona.checksums --execute --databases test [root@mysql.dmc.com ~]$pt-table-sync --user=checksum --password=checksum h=10.1.16.74 h=10.1.16.76 --replicate percona.checksums --execute --databases test
同步test库的不一致
# at 61854 #150909 14:46:35 server id 1 end_log_pos 62290 CRC32 0x226770f7 Query thread_id=231653 exec_time=0 error_code=0 SET TIMESTAMP=1441781195/*!*/; REPLACE INTO `test`.`t_order`(`order_id`, `customer_id`) VALUES ('6', '6') /*percona-toolkit src_db:test src_tbl:t_order src_dsn:h=10.1.16.74,p=...,u=checksum dst_db:test dst_tbl:t_order dst_dsn:h=slave_16.76,p=...,u=checksum lock:1 transaction:1 changing_src:percona.checksums replicate:percona.checksums bidirectional:0 pid:11064 user:root host:mysql.dmc.com*//*!*/; /*!*/;
进行同步后,可以看master上的binlog或者看slave中的relaylog都可以看到如上的日志,这里就看出sync的原理了。
但是,没有通过checksum的方式 进行sync,直接修改从库,就不会在主上有binlog了。
[root@mysql.dmc.com mysql]$pt-table-sync --user=checksum --password=checksum h=10.1.16.74,D=test,t=t_order h=10.1.16.76 --print UPDATE `test`.`t_order` SET `customer_id`='6' WHERE `order_id`='6' LIMIT 1 /*percona-toolkit src_db:test src_tbl:t_order src_dsn:D=test,h=10.1.16.74,p=...,t=t_order,u=checksum dst_db:test dst_tbl:t_order dst_dsn:D=test,h=10.1.16.76,p=...,t=t_order,u=checksum lock:0 transaction:1 changing_src:0 replicate:0 bidirectional:0 pid:11559 user:root host:mysql.dmc.com*/; [root@mysql.dmc.com mysql]$pt-table-sync --user=checksum --password=checksum h=10.1.16.74,D=test,t=t_order h=10.1.16.76 --execute
你会很清楚发现,直接根据主库数据修改从库的数据时,产生的sql是不一样的。直接修改从库是update,而通过checksum修改者是repalce into。
[root@mysql.dmc.com mysql]$pt-table-sync --user=checksum --password=checksum h=10.1.16.74,D=test,t=t_order h=10.1.16.76 --replicate percona.checksums --print REPLACE INTO `test`.`t_order`(`order_id`, `customer_id`) VALUES ('6', '6') /*percona-toolkit src_db:test src_tbl:t_order src_dsn:D=test,h=10.1.16.74,p=...,t=t_order,u=checksum dst_db:test dst_tbl:t_order dst_dsn:D=test,h=10.1.16.76,p=...,t=t_order,u=checksum lock:1 transaction:1 changing_src:percona.checksums replicate:percona.checksums bidirectional:0 pid:11550 user:root host:mysql.dmc.com*/;
主要看--replicate percona.checksums 这个参数
如果是master-master架构,或者slave开启了binlog,主要是为了数据安全。直接修改就会提示如下:
[root@mysql.dmc.com mysql]$pt-table-sync --user=checksum --password=checksum h=10.1.16.74,D=test,t=t_order h=10.1.16.76 --print Can't make changes on D=test,h=10.1.16.76,p=...,t=t_order,u=checksum because it's a slave. See the documentation section 'REPLICATION SAFETY' for solutions to this problem. at /usr/bin/pt-table-sync line 10669. while doing test.t_order on 10.1.16.76 Can't make changes on D=test,h=10.1.16.76,p=...,t=t_order,u=checksum because it's a slave. See the documentation section 'REPLICATION SAFETY' for solutions to this problem. at /usr/bin/pt-table-sync line 10669. while doing test.t_order on 10.1.16.76
可以通过--no-bin-log参数来解决,不记录bin-log,不然在主主架构上会导致复制回去。
[root@mysql.dmc.com mysql]$pt-table-sync --user=checksum --password=checksum h=10.1.16.74,D=test,t=t_order h=10.1.16.76 --print --no-bin-logUPDATE `test`.`t_order` SET `customer_id`='6' WHERE `order_id`='6' LIMIT 1 /*percona-toolkit src_db:test src_tbl:t_order src_dsn:D=test,h=10.1.16.74,p=...,t=t_order,u=checksum dst_db:test dst_tbl:t_order dst_dsn:D=test,h=10.1.16.76,p=...,t=t_order,u=checksum lock:0 transaction:1 changing_src:0 replicate:0 bidirectional:0 pid:11559 user:root host:mysql.dmc.com*/; UPDATE `test`.`t_order` SET `customer_id`='6' WHERE `order_id`='6' LIMIT 1 /*percona-toolkit src_db:test src_tbl:t_order src_dsn:D=test,h=10.1.16.74,p=...,t=t_order,u=checksum dst_db:test dst_tbl:t_order dst_dsn:D=test,h=10.1.16.76,p=...,t=t_order,u=checksum lock:0 transaction:1 changing_src:0 replicate:0 bidirectional:0 pid:11559 user:root host:mysql.dmc.com*/;
前面这些测试t_order 表是有主键和唯一索引的,如果没有通过checksum就无法进行修复:
[test]> show create table t5; CREATE TABLE `t5` ( `id` int(11) DEFAULT NULL, `dt` datetime NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (TO_DAYS(dt)) (PARTITION p0 VALUES LESS THAN (735599) ENGINE = InnoDB, PARTITION p1 VALUES LESS THAN (735630) ENGINE = InnoDB, PARTITION p2 VALUES LESS THAN (735658) ENGINE = InnoDB, PARTITION p3 VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */ | [root@mysql.dmc.com mysql]$pt-table-sync --user=checksum --password=checksum h=10.1.16.74,D=test,t=t5 h=10.1.16.76 --replicate percona.checksums --print Can't make changes on the master because no unique index exists at /usr/bin/pt-table-sync line 10648. while doing test.t5 on 10.1.16.76 Can't make changes on the master because no unique index exists at /usr/bin/pt-table-sync line 10648. while doing test.t5 on 10.1.16.76
这是由于test.t5没有唯一索引导致,如果需要修复可选择如下方式。
[root@mysql.dmc.com mysql]$pt-table-sync --user=checksum --password=checksum h=10.1.16.74,D=test,t=t5 h=10.1.16.76 --print --no-bin-log DELETE FROM `test`.`t5` WHERE `id`='2' AND `dt`='2015-09-07 16:26:00' LIMIT 1 /*percona-toolkit src_db:test src_tbl:t5 src_dsn:D=test,h=10.1.16.74,p=...,t=t5,u=checksum dst_db:test dst_tbl:t5 dst_dsn:D=test,h=10.1.16.76,p=...,t=t5,u=checksum lock:0 transaction:1 changing_src:0 replicate:0 bidirectional:0 pid:12026 user:root host:mysql.dmc.com*/;INSERT INTO `test`.`t5`(`id`, `dt`) VALUES ('2', '2015-09-07 00:00:00') /*percona-toolkit src_db:test src_tbl:t5 src_dsn:D=test,h=10.1.16.74,p=...,t=t5,u=checksum dst_db:test dst_tbl:t5 dst_dsn:D=test,h=10.1.16.76,p=...,t=t5,u=checksum lock:0 transaction:1 changing_src:0 replicate:0 bidirectional:0 pid:12026 user:root host:mysql.dmc.com*/; INSERT INTO `test`.`t5`(`id`, `dt`) VALUES ('2', '2015-09-07 00:00:00') /*percona-toolkit src_db:test src_tbl:t5 src_dsn:D=test,h=10.1.16.74,p=...,t=t5,u=checksum dst_db:test dst_tbl:t5 dst_dsn:D=test,h=10.1.16.76,p=...,t=t5,u=checksum lock:0 transaction:1 changing_src:0 replicate:0 bidirectional:0 pid:12026 user:root host:mysql.dmc.com*/;
没有唯一索引的数据修复是通过delete后再insert,把print改为execute即可修复。