赞
踩
在理想情况下,备库和主库的数据应该是完全一样的。但事实上备库可能发生错误并导致数据不一致。即使没有明显的错误,备库同样可能因为 MySQL 自身的特性导致数据不一致,例如 MySQL 的Bug感、网络中断、服务器宕机等,非正常关闭或者其他一些错误。
按照我们的经验来看,主备一致应该是一种规范,而不是例外,也就是说,检查你的主备库一致性应该是一个日常工作,特别是当使用备库来做备份时尤为重要,因为肯定不希望从一个已经损坏的备库里获得备份数据。
我们可以使用 percona-toolkit 工具做校验,而该工具包含:
在主库安装:
工具可以下载可以看这个文章:https://blog.csdn.net/qq_39408664/article/details/119378696
# 安装插件
[root@localhost src]# yum install perl-IO-Socket-SSL perl-DBD-MySQL perl-Time-HiRes perl perl-DBI -y
# 安装本地工具
[root@localhost src]# yum -y localinstall percona-toolkit-3.2.1-1.el7.x86_64.rpm
# 查看列表
[root@localhost src]# yum list | grep percona-toolkit
percona-toolkit.x86_64 3.2.1-1.el7 installed
# 查看帮助
[root@localhost src]# pt-table-checksum --help
使用方法:
pt-table-checksum [options] [dsn]
pt-table-checksum:在主(Master)上通过执行校验的查询对复制的一致性进行检查,对比主从的校验值,从而产生结果。DSN指向的是主的地址,该工具的退出状态不为零,如果发现有任何差别,或者如果出现任何警告或错误,更多信息请查看官方资料。
现在我们可以准备一个动作:来模拟数据不一致的问题,同时需要确保主从是配置好了的 -》思路就是创建一个test的库随便添加一个表:
# 创建库
create database `mytest`;
# 创建表
create table user (
id int(10) primary key,
name varchar(20)
);
首先在主库新增数据:
# 进入数据库 mysql> use mytest; # 写入几条数据 mysql> insert into user (id,name)values(1,'xiaoming'); mysql> insert into user (id,name)values(2,'php'); mysql> insert into user (id,name)values(3,'java'); mysql> insert into user (id,name)values(4,'python'); # 查询一下 mysql> select * from user; +----+----------+ | id | name | +----+----------+ | 1 | xiaoming | | 2 | php | | 3 | java | | 4 | python | +----+----------+ 4 rows in set (0.00 sec)
其次是在从库操作;此时因为主从复制的原因,在上面主库进行的操作都会被复制到从库。
# 进入数据库 mysql> use mytest; # 写入一条数据 mysql> insert into user (id,name)values(5,'html'); # 查询数据 mysql> select * from user; +----+----------+ | id | name | +----+----------+ | 1 | xiaoming | | 2 | php | | 3 | java | | 4 | python | | 5 | html | +----+----------+ 5 rows in set (0.00 sec)
从上面可以看到实际上数据是不同步的,也就是主库的数据少于从库的数据。
使用工具检测
注意常用的参数解释:
--nocheck-replication-filters
:不检查复制过滤器,建议启用。后面可以用–databases来指定需要检查的数据库。
--no-check-binlog-format
: 不检查复制的binlog模式,要是binlog模式是ROW,则会报错。
--replicate-check-only
:只显示不同步的信息。
--replicate=
:把checksum的信息写入到指定表中,建议直接写到被检查的数据库当中。
--databases=
:指定需要被检查的数据库,多个则用逗号隔开。
--tables=
:指定需要被检查的表,多个用逗号隔开
--host | h=
:Master的地址
--user | u=
:用户名
--password | p=
:密码
--Post | P=
:端口
检测
在检测中遇到问题请看这个文章(包含了大部分问题讲解):https://blog.csdn.net/qq_39408664/article/details/119445937
# 执行检测命令 #--replicate=check_data.checksums 这个是错误写入的表,不用手动创建,执行命令后自动创建的,可以修改 #--user --password 主库从库需要一致 [root@localhost ~]# pt-table-checksum --nocheck-replication-filters --no-check-binlog-format --replicate=check_data.checksums --databases=mytest --tables=user --user=mytest_slave --password=root Checking if all tables can be checksummed ... Starting checksum ... TS ERRORS DIFFS ROWS DIFF_ROWS CHUNKS SKIPPED TIME TABLE 08-06T10:30:32 0 1 8 0 1 0 0.037 mytest.user # 显示这样即代表没有问题运行成功了。 # Checking if all tables can be checksummed ... 代表开始检测校验表和库 # Starting checksum ... 代表开始校验信息 # TS 代表完成检查的时间 # ERRORS 检查时候发生错误和警告的数量 # DIFFS 0代表数据一致 1表示不一致;当指定--no-replicate-check时,会一直为0,当指定--replicate-check-only会显示不同的信息。 # ROWS 表的行数 # CHUNKS 被划分到表中的块的数目 # SKIPPED 由于错误或警告过大,则跳过块的数目 # TIME 执行时间 # TABLE 被检查的表名
哪些信息数据会记录在 checksums 表中
mysql> use check_data; mysql> show tables; +----------------------+ | Tables_in_check_data | +----------------------+ | checksums | +----------------------+ 1 row in set (0.00 sec) # 查看信息 mysql> select * from checksums \G; *************************** 1. row *************************** db: mytest tbl: user chunk: 1 chunk_time: 0.002004 chunk_index: NULL lower_boundary: NULL upper_boundary: NULL this_crc: 30058a09 this_cnt: 8 master_crc: 30058a09 master_cnt: 8 ts: 2021-08-06 10:52:35 1 row in set (0.00 sec) ERROR: No query specified
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。