pt-检查数据一致性

一、安装percona-toolkit

1、下载

wget -P /usr/software https://www.percona.com/downloads/percona-toolkit/3.0.3/binary/redhat/6/x86_64/percona-toolkit-3.0.3-1.el6.x86_64.rpm

2、安装依赖

yum install perl-IO-Socket-SSL perl-DBD-MySQL perl-Time-HiRes -y

3、安装工具

yum -y localinstall /usr/software/percona-toolkit-3.0.3-1.el6.x86_64.rpm
rpm -qa | grep percona-toolkit

二、检查主从数据一致性

检查方法

1、主从均安装pt工具

2、为主从添加检查用户

#添加check用户,需要授权SELECT, PROCESS, SUPER, REPLICATION
GRANT SELECT,PROCESS,SUPER,REPLICATION SLAVE,CREATE,DELETE,INSERT,UPDATE ON *.* TO ‘checksum‘@‘10.11.%.%‘ identified by ‘checksumpasswd‘;
flush privileges;

3、检查

pt-table-checksum --nocheck-replication-filters --no-check-binlog-format --replicate=cnt.checksums --databases=wallet h=masterIP,u=checksum,p=checksumpasswd,P=3306
#参数说明
--no-check-replication-filters 表示不需要检查 Master 配置里是否指定了 Filter(replicate_do_db,replicate-wild-ignore-table,binlog_ignore_db 等),官方默认是yes(--check-replication-filters),可能出现表不存在而报错退出,如指定--databases=,所以就不存在这个问题,所以可以不检测。
--no-check-binlog-format 不对binlog的格式进行检查
--replicate-check-only  只显示主从不一致部分,此参数不会生成新的checksums数据,只会根据checksums表已经有的数据来显示
--databases=,-d:要检查的数据库,逗号分隔。 --databases-regex 正则匹配要检测的数据库,--ignore-databases[-regex]忽略检查的库,检查全库。
--tables=,-t:要检查的表,逗号分隔。如果要检查的表分布在不同的db中,可以用--tables=dbname1.table1,dbnamd2.table2的形式。
同理有--tables-regex,--ignore-tables,--ignore-tables-regex。--replicate指定的checksum表始终会被过滤。

实验环境及检查结果

travel库
1、新增表情况

主库新增表tmp_2
检查结果:
提示Table travel.tmp_2 does not exist on replica mysql-s

2、删除表情况

主库删除表tmp_1;
检查结果:
删除的tmp_1没有提示

3、表中新增数据情况

tmp表新增一条数据| 266 | 2020031100000165 |            4 |
检查结果:
可以查验出

4、表中删除数据情况

tmp删除一条数据    265 | 2019042300000164 |            0
检查结果:
可以查验出

5、错误处理

如出现如下错误
    Waiting to check replicas for differences:   0% 00:00 remain

方法一:配置文件设置autocommit=ON 重启数据库

方法二:(可能仍然不行)    
可进行如下操作(主从均修改)
    
在下面代码后添加$master_dbh->do("commit");
如下
         $update_sth->execute(
            # UPDATE repl_table SET
            sprintf(‘%.6f‘, $tbl->{nibble_time}), # chunk_time
            $crc,                                 # master_crc
            $cnt,                                 # master_cnt
            # WHERE
            $tbl->{db},
            $tbl->{tbl},
            $chunk,
         );
         $master_dbh->do("commit");

         在下面代码后添加$dbh->do("commit");
如下
        $sth->{nibble}->execute(
            # REPLACE INTO repl_table SELECT
            $tbl->{db},             # db
            $tbl->{tbl},            # tbl
            $chunk,                 # chunk (number)
            $chunk_index,           # chunk_index
            $lb_quoted,             # lower_boundary
            $ub_quoted,             # upper_boundary
            # this_cnt, this_crc WHERE
            @{$boundary->{lower}},  # upper boundary values
            @{$boundary->{upper}},  # lower boundary values
        );
        $dbh->do("commit");
        
修改之后,关闭autocommit ,并清空percona.checksums

三、修复不一致数据

从上执行

pt-table-sync --print --sync-to-master h=slaveIP,P=3306,u=checksum,p=‘checksumpasswd‘ --databases=travel --tables=tmp

结果可打印出需要执行的语句

# A software update is available:
#   * The current version for Percona::Toolkit is 3.0.5

DELETE FROM `travel`.`tmp` WHERE `id`=‘265‘ LIMIT 1 /*percona-toolkit src_db:travel src_tbl:tmp src_dsn:P=3306,h=masterIP,p=...,u=checksum dst_db:travel dst_tbl:tmp dst_dsn:P=3306,h=slaveIP,p=...,u=checksum lock:1 transaction:1 changing_src:1 replicate:0 bidirectional:0 pid:1774 user:root host:mysql-s-57*/;
REPLACE INTO `travel`.`tmp`(`id`, `order_code`, `order_status`) VALUES (‘266‘, ‘2020031100000165‘, ‘4‘) /*percona-toolkit src_db:travel src_tbl:tmp src_dsn:P=3306,h=masterIP,p=...,u=checksum dst_db:travel dst_tbl:tmp dst_dsn:P=3306,h=slaveIP,p=...,u=checksum lock:1 transaction:1 changing_src:1 replicate:0 bidirectional:0 pid:1774 user:root host:mysql-s-57*/;

从库执行上面打印结果的语句修复数据

DELETE FROM `travel`.`tmp` WHERE `id`=‘265‘ LIMIT 1;
REPLACE INTO `travel`.`tmp`(`id`, `order_code`, `order_status`) VALUES (‘266‘, ‘2020031100000165‘, ‘4‘);

执行完成后再次检查数据一致性

相关推荐