【mysql】pt工具之pt-table-sync

【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即可修复。

 

时间:2015-09-09 04:09:34      作者:beebol      标签: mysql pt-table-rsync      分类: mysql
  • 分享到:
  • 微博
  • QQ空间
  • 腾讯微博
  • 微信

Copyright © 2015 Gitblog | Proudly powered by Gitblog.