MySQL验证主从一致、主从不一致修复(整理)
Percona Toolkit 是一组高级的命令行工具,用来管理 MySQL 和系统任务,主要包括:
- 验证主节点和复制数据的一致性
- 有效的对记录行进行归档
- 找出重复的索引
- 总结 MySQL 服务器
- 从日志和 tcpdump 中分析查询
- 问题发生时收集重要的系统信息
安装:
yum localinstall https://www.percona.com/downloads/percona-toolkit/2.2.17/RPM/percona-toolkit-2.2.17-1.noarch.rpm
使用方法:
pt-table-checksum [OPTIONS] [DSN]
pt-table-checksum
:在主(master)上通过执行校验的查询对复制的一致性进行检查,对比主从的校验值,从而产生结果。DSN指向的是主的地址,该工具的退出状态不为零,如果发现有任何差别,或者如果出现任何警告或错误,更多信息请查看官方资料。
下面通过实际的例子来解释该工具如何使用:
主库:
mysql> select * from student;
+----+------+-------+-------+
| id | name | class | score |
+----+------+-------+-------+
| 1 | a | 1 | 56 |
| 2 | b | 1 | 61 |
| 3 | c | 2 | 78 |
| 4 | d | 2 | 45 |
| 5 | e | 3 | 76 |
| 6 | f | 3 | 89 |
| 7 | g | 4 | 43 |
| 8 | h | 4 | 90 |
+----+------+-------+-------+
8 rows in set (0.00 sec)
从库:
mysql> select * from student;
+----+------+-------+-------+
| id | name | class | score |
+----+------+-------+-------+
| 1 | a | 1 | 56 |
| 3 | c | 2 | 78 |
| 4 | d | 2 | 45 |
| 5 | e | 3 | 76 |
| 7 | g | 4 | 43 |
| 8 | h | 4 | 90 |
+----+------+-------+-------+
6 rows in set (0.00 sec)
可以看到数据是不一致的,用工具来检测一下:
首先,
- 根据测试,需要一个即能登录主库,也能登录从库的账号;
- 只能指定一个host,必须为主库的IP;
- 在检查时会向表加S锁;
- 运行之前需要从库的同步IO和SQL进程是YES状态。
主库默认登录不需要密码,需要给主库加密码登录:
mysql> GRANT SELECT, PROCESS, SUPER, REPLICATION SLAVE ON *.* TO 'root'@'127.0.0.1' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
从库同样要授权:
mysql GRANT SELECT, PROCESS, SUPER, REPLICATION SLAVE ON . TO 'root'@'192.168.31.110' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.00 sec)
mysql flush privileges;
Query OK, 0 rows affected (0.00 sec)
执行检查:
pt-table-checksum --nocheck-replication-filters --replicate=abc.checksums --databases=abc --tables=student h=127.0.0.1,u=root,p=123456,P=3306
Replica xxx has binlog_format MIXED which could cause pt-table-checksum to break replication. Please read "Replicas using row-based replication" in the LIMITATIONS section of the tool's documentation. If you understand the risks, specify --no-check-binlog-format to disable this check.
执行报错了,因为我们当前的binlog_format = mixed
,默认情况下,pt-table-checksum
只能检测STATEMENT格式的binlog,我们可以用 --no-check-binlog-format
参数关闭检查。
pt-table-checksum --nocheck-replication-filters --no-check-binlog-format --replicate=abc.checksums --databases=abc --tables=student h=127.0.0.1,u=root,p=123456,P=3306
TS ERRORS DIFFS ROWS CHUNKS SKIPPED TIME TABLE
03-25T10:31:51 0 1 8 1 0 0.014 abc.student
OK,检查到了数据不一致。
字段说明
TS :完成检查的时间。
ERRORS :检查时候发生错误和警告的数量。
DIFFS :0表示一致,1表示不一致。当指定--no-replicate-check时,会一直为0,当指定--replicate-check-only会显示不同的信息。
ROWS :表的行数。
CHUNKS :被划分到表中的块的数目。
SKIPPED :由于错误或警告或过大,则跳过块的数目。
TIME :执行的时间。
TABLE :被检查的表名。
命令参数说明
--nocheck-replication-filters :不检查复制过滤器,建议启用。后面可以用--databases来指定需要检查的数据库。
--no-check-binlog-format : 不检查复制的binlog模式,要是binlog模式是ROW,则会报错。
--replicate-check-only :只显示不同步的信息。
--replicate= :把checksum的信息写入到指定表中,建议直接写到被检查的数据库当中。
--databases= :指定需要被检查的数据库,多个则用逗号隔开。
--tables= :指定需要被检查的表,多个用逗号隔开
h=127.0.0.1 :Master的地址
u=root :用户名
p=123456 :密码
P=3306 :端口
通过DIFFS是1可以看出主从的表数据不一致。通过查看从库上的test.checksum表可以看到主从库的检验信息。
mysql select * from checksums\G;
********* 1. row *********
db: abc
tbl: student
chunk: 1
chunk_time: 0.002583
chunk_index: NULL
lower_boundary: NULL
upper_boundary: NULL
this_crc: 4013c678 #从的校验值
this_cnt: 6 #从的行数
master_crc: 6eb6ef78 #主的校验值
master_cnt: 8 #主的行数
ts: 2016-03-25 10:42:41
1 row in set (0.00 sec)
修复数据:
pt-table-sync --print --replicate=abc.checksums h=127.0.0.1,u=root,p=123456,P=3306 h=192.168.31.111,u=root,p=123456,P=3306
REPLACE INTOabc
.student
(id
,name
,class
,score
) VALUES ('2', 'b', '1', '61') /percona-toolkit src_db:abc src_tbl:student src_dsn:P=3306,h=127.0.0.1,p=...,u=root dst_db:abc dst_tbl:student dst_dsn:P=3306,h=192.168.31.111,p=...,u=root lock:1 transaction:1 changing_src:abc.checksums replicate:abc.checksums bidirectional:0 pid:32499 user:root host:xxx/;
REPLACE INTOabc
.student
(id
,name
,class
,score
) VALUES ('6', 'f', '3', '89') /percona-toolkit src_db:abc src_tbl:student src_dsn:P=3306,h=127.0.0.1,p=...,u=root dst_db:abc dst_tbl:student dst_dsn:P=3306,h=192.168.31.111,p=...,u=root lock:1 transaction:1 changing_src:abc.checksums replicate:abc.checksums bidirectional:0 pid:32499 user:root host:xxx/;
将不一致的数据用SQL命令打印出来了,我们可以拿命令去从库上执行,也可以加--execute自动执行
pt-table-sync --print --replicate=abc.checksums h=127.0.0.1,u=root,p=123456,P=3306 h=192.168.31.111,u=root,p=123456,P=3306 --execute
REPLACE INTOabc
.student
(id
,name
,class
,score
) VALUES ('2', 'b', '1', '61') /percona-toolkit src_db:abc src_tbl:student src_dsn:P=3306,h=127.0.0.1,p=...,u=root dst_db:abc dst_tbl:student dst_dsn:P=3306,h=192.168.31.111,p=...,u=root lock:1 transaction:1 changing_src:abc.checksums replicate:abc.checksums bidirectional:0 pid:32506 user:root host:xxx/;
REPLACE INTOabc
.student
(id
,name
,class
,score
) VALUES ('6', 'f', '3', '89') /percona-toolkit src_db:abc src_tbl:student src_dsn:P=3306,h=127.0.0.1,p=...,u=root dst_db:abc dst_tbl:student dst_dsn:P=3306,h=192.168.31.111,p=...,u=root lock:1 transaction:1 changing_src:abc.checksums replicate:abc.checksums bidirectional:0 pid:32506 user:root host:xxx/;
修复完成,再次查看从库:
mysql> select * from student;
+----+------+-------+-------+
| id | name | class | score |
+----+------+-------+-------+
| 1 | a | 1 | 56 |
| 2 | b | 1 | 61 |
| 3 | c | 2 | 78 |
| 4 | d | 2 | 45 |
| 5 | e | 3 | 76 |
| 6 | f | 3 | 89 |
| 7 | g | 4 | 43 |
| 8 | h | 4 | 90 |
+----+------+-------+-------+
8 rows in set (0.00 sec)