【Percona-Toolkit】系列之pt-table-checksum和pt-table-sync 数据校验修复神器

简介

这次主要包含两个工具,都可以在percona-tookit里面找到

  • pt-table-checksum
  • pt-table-sync

pt-table-checksum

#简介
pt-table-checksum主要可以用来校验主从数据的一致性,一主多从,一主单从都可以
 
#常用参数
--no-check-replication-filters      不检查复制过滤
--no-check-binlog-format            不检查binlog格式,因为binlog这里需要使用statement格式
--replicate                         检查的结果写到,哪个db的checksums表中
CREATE TABLE checksums (
   db             CHAR(64)     NOT NULL,
   tbl            CHAR(64)     NOT NULL,
   chunk          INT          NOT NULL,
   chunk_time     FLOAT            NULL,
   chunk_index    VARCHAR(200)     NULL,
   lower_boundary TEXT             NULL,
   upper_boundary TEXT             NULL,
   this_crc       CHAR(40)     NOT NULL,
   this_cnt       INT          NOT NULL,
   master_crc     CHAR(40)         NULL,
   master_cnt     INT              NULL,
   ts             TIMESTAMP    NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
   PRIMARY KEY (db, tbl, chunk),
   INDEX ts_db_tbl (ts, db, tbl)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--chunk-size                        默认1000条记录一个chunk去做query
--ignore-columns                    指定需要忽略校验的字段,如有多个则用','(逗号)隔开。
--ignore-databases                  指定需要忽略校验的数据库,如有多个则用','(逗号)隔开。
--ignore-databases-regex            指定采用正则表达式匹配忽略校验的数据库。
--ignore-engines                    默认值:FEDERATED,MRG_MyISAM指定需要忽略校验的存储引擎类型的表,如有多个则用','(逗号)隔开。
--ignore-tables                     忽略检查哪个表
--ignore-tables-regex               忽略检查哪个表,政策表达式
--max-lag                           主从延迟达到多少就停止,默认1s
--max-load                          可以指定负载,默认threads-running=25
--progress                          进度
--tables                            check表
--tables-regex=user_watch_tab*      只check哪个表,正则表达式
--ask-pass                          需要显示输入密文
--replicate-check-only              只校验结果不一致的数据库
--recursion-method                  默认值:processlist,hosts
指定获取从库的方式。pt-table-checksum在执行校验操作时会执行多次REPLICA CHECKS操作。
METHOD       USES
===========  =============================================
processlist  SHOW PROCESSLIST  
hosts        SHOW SLAVE HOSTS  
cluster      SHOW STATUS LIKE 'wsrep\_incoming\_addresses'
dsn=DSN      DSNs from a table
none         Do not find slaves
==========================================================
processlist:通过SHOW PROCESSLIST方式找到slave,为默认方式,当SHOW SLAVE HOSTS不可用时。一旦实例运行在非3306端口上时,hosts方式就会变为默认方式;
hosts:通过SHOW SLAVE HOSTS方式找到slave,hosts方式要求从库配置'--report_host''--report_port'这两个参数;
cluster:基于集群版本Galera 23.7.3及更新版本;
dsn:通过读取表中从库的DSN信息进行连接。
dsn是表,对于多个slave的时候,dsn表最好
 
CREATE TABLE `dsns` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `parent_id` int(11) DEFAULT NULL,
  `dsn` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
);
 
#检查不一致的sql
SELECT db, tbl, SUM(this_cnt) AS total_rows, COUNT(*) AS chunks
FROM percona.checksums
WHERE (
 master_cnt <> this_cnt
 OR master_crc <> this_crc
 OR ISNULL(master_crc) <> ISNULL(this_crc))
GROUP BY db, tbl;

pt-table-sync

#简介
用于修复主从不一致的数据
 
#常用参数
--replicate=  :指定通过pt-table-checksum得到的表,这2个工具差不多都会一直用。
--databases=  : 指定执行同步的数据库,多个用逗号隔开。
--tables=     :指定执行同步的表,多个用逗号隔开。
--sync-to-master :指定一个DSN,即从的IP,他会通过show processlist或show slave status 去自动的找主。
h=127.0.0.1   :服务器地址,命令里有2个ip,第一次出现的是Master的地址,第2次是Slave的地址。
u=root        :帐号。
p=123456      :密码。
--print       :打印,但不执行命令。
--execute     :执行命令。
--transaction 指定工具操作使用事务代替LOCK TABLES语句进行锁表。
--verbose.  打印出更详细的信息
--recursion-method 获得从库的信息,默认值:processlist,hosts 还有另外一个none
 
 
#常用用法
1.Resolve differences that pt-table-checksum found on all slaves of master1:
pt-table-sync --execute --replicate test.checksum master1
2.Same as above but only resolve differences on slave1
pt-table-sync --execute --replicate test.checksum \
  --sync-to-master slave1
 
#注意点
如果使用了非3306端口,会使用show slave hosts去获得ip,查找slave。
如果拿掉外网IP这些会导致找不到slave,不能一次性操作多个
需要一个一个以上面第二种方式操作。

实际操作

#实际用法
 
#1.先在master上创建用户,可以连接到所有slave,并授权
create user 'pt-table-check'@'master_ip' identified by '$pass';
grant SELECT, PROCESS, SUPER, REPLICATION SLAVE,lock tables on *.* to 'pt-table-check'@'master_ip';
grant CREATE, INSERT, UPDATE, DELETE on test.* to 'pt-table-check'@'master_ip';
 
#2.master创建dsn slave table表,并插入数据
CREATE TABLE `test`.`dsns` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parent_id` int(11) DEFAULT NULL,
`dsn` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
);
insert into test.dsns(dsn) values ("h=s1ip,P=6606,u=pt-table-check,p=");
insert into test.dsns(dsn) values ("h=s2ip,P=6606,u=pt-table-check,p=");
insert into test.dsns(dsn) values ("h=s3ip,P=6606,u=pt-table-check,p=");
insert into test.dsns(dsn) values ("h=s4ip,P=6606,u=pt-table-check,p=");
insert into test.dsns(dsn) values ("h=s5ip,P=6606,u=pt-table-check,p=");
insert into test.dsns(dsn) values ("h=s6ip,P=6606,u=pt-table-check,p="); 
 
#3.开始进行check,这里进行正则匹配
pt-table-checksum h=master_ip,P=6606,u='pt-table-check' --no-check-replication-filters --no-check-binlog-format --ask-pass --max-lag=1 --max-load='Threads_running=25' --replicate=test.checksums --databases=jiawei_test --tables-regex=user_watch_tab* --recursion-method dsn=h=dsn表的ip,u='pt-table-check',p='$pass',P=6606,D=test,t=dsns
 
Checksumming jiawei_test.user_watch_tab_00000041:  22% 01:42 remain
Checksumming jiawei_test.user_watch_tab_00000041:  42% 01:22 remain
Checksumming jiawei_test.user_watch_tab_00000041:  62% 00:54 remain
Checksumming jiawei_test.user_watch_tab_00000041:  85% 00:20 remain
06-16T19:52:32      0      1 50933486          0     207       0 173.857 jiawei_test.user_watch_tab_00000041
 
#4.slave查询结果表,查看不一致的
SELECT db, tbl, SUM(this_cnt) AS total_rows, COUNT(*) AS chunks
FROM percona.checksums
WHERE (
 master_cnt <> this_cnt
 OR master_crc <> this_crc
 OR ISNULL(master_crc) <> ISNULL(this_crc))
GROUP BY db, tbl;
 
>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 |
+------------------+-------------------------+------------+--------+
| jiawei_test	   | user_watch_tab_00000000 |     258163 |      1 |
| jiawei_test      | user_watch_tab_00000003 |     244324 |      1 |
| jiawei_test 	   | user_watch_tab_00000004 |     252323 |      1 |
| jiawei_test	   | user_watch_tab_00000006 |     246460 |      1 |
| jiawei_test	   | user_watch_tab_00000011 |     248913 |      1 |
| jiawei_test	   | user_watch_tab_00000016 |     248169 |      1 |
| jiawei_test 	   | user_watch_tab_00000020 |     247681 |      1 |
| jiawei_test	   | user_watch_tab_00000021 |     241514 |      1 |
| jiawei_test 	   | user_watch_tab_00000022 |     247455 |      1 |
| jiawei_test 	   | user_watch_tab_00000025 |     249253 |      1 |
| jiawei_test 	   | user_watch_tab_00000028 |     255769 |      1 |
| jiawei_test 	   | user_watch_tab_00000034 |     247704 |      1 |
| jiawei_test	   | user_watch_tab_00000041 |     249859 |      1 |
| jiawei_test 	   | user_watch_tab_00000053 |     251265 |      1 |
| jiawei_test 	   | user_watch_tab_00000056 |     245363 |      1 |
| jiawei_test 	   | user_watch_tab_00000065 |     245756 |      1 |
| jiawei_test 	   | user_watch_tab_00000072 |     246405 |      1 |
| jiawei_test 	   | user_watch_tab_00000077 |     249218 |      1 |
| jiawei_test	   | user_watch_tab_00000084 |     253561 |      1 |
| jiawei_test 	   | user_watch_tab_00000091 |     249323 |      1 |
| jiawei_test	   | user_watch_tab_00000098 |     248128 |      1 |
+------------------+-------------------------+------------+--------+
21 rows in set (0.02 sec)
 
#5.是用pt-table-sync可以先打印出来数据,简单check下
#如果是3306端口,且可以通过show slave hosts找到地址
pt-table-sync --print --replicate test.checksum h=masterip,P=6606,u='pt-table-check' --transaction --verbose --ask-pass
#如果上述不满足
pt-table-sync --print --replicate test.checksums --sync-to-master h=s1ip,P=6606,u='pt-table-check' --ask-pass --transaction --verbose
可以手动执行,注意sql-log-bin=0,不要写binlog
也可以直接--execute自动执行
 
#master执行
# pt-table-sync --print --replicate test.checksums --sync-to-master h=s1ip,P=6606,u='pt-table-check' --ask-pass --transaction --verbose 2>&1 >> /data/scripts/repair.sql
Enter password for s1ip:
# Syncing via replication P=6606,h=s1ip,p=...,u=pt-table-check
# DELETE REPLACE INSERT UPDATE ALGORITHM START    END      EXIT DATABASE.TABLE
REPLACE INTO `jiawei_test`.`user_watch_tab_00000000`(column_names) VALUES (values) /*percona-toolkit src_db:jiawei_test src_tbl:user_watch_tab_00000000 src_dsn:P=6606,h=master_ip,p=...,u=pt-table-check dst_db:jiawei_test dst_tbl:user_watch_tab_00000000 dst_dsn:P=6606,h=s1ip,p=...,u=pt-table-check lock:1 transaction:1 changing_src:test.checksums replicate:test.checksums bidirectional:0 pid:9758 user:root hostname*/;
 
#获取执行结果然后执行
mysql -u -p -e "set sql_log_bin=0;source /data/scripts/repair.sql;"

#6.check一下数据是否一样了
主从分别查询修复的数据是否一致。
至此数据修复完毕。
 
#备注
分析的时候会对对应的块加锁。

操作的时候会有压力?

可以看到我在线上操作的时候数据库基本没有任何压力。该工具并不会对数据库产生任何性能影响。
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

渔不是鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值