MySQL主从复制状态及数据一致性监测工具
url:https://www.cnblogs.com/kevingrace/p/6261091.html
一、percona-toolkit工具介绍
percona-toolkit工具中最主要的三个组件分别是:
1.pt-table-checksum 负责监测mysql主从数据一致性
2.pt-table-sync 负责当主从数据不一致时修复数据,让它们保存数据的一致性
3.pt-heartbeat 负责监控mysql主从同步延迟
二、percona-toolkit工具安装
建议:master端和slave端都安装percona-toolkit工具
2.1 安装依赖包
[root@host-39-108-217-12 ~]# yum install perl-IO-Socket-SSL perl-DBD-MySQL perl-Time-HiRes perl perl-DBI -y
2.2 安装percona-toolkit
下载url:https://www.percona.com/downloads/percona-release/redhat/0.1-6/
[root@host-39-108-217-12 ~]# wget https://www.percona.com/redir/downloads/percona-release/redhat/0.1-6/percona-release-0.1-6.noarch.rpm
[root@host-39-108-217-12 ~]# yum install percona-release-0.1-6.noarch.rpm
[root@host-39-108-217-12 ~]# yum list | grep percona-toolkit
percona-toolkit.noarch 2.2.20-1 percona-release-noarch
percona-toolkit.x86_64 3.0.10-1.el7 percona-release-x86_64
percona-toolkit-debuginfo.x86_64 3.0.10-1.el7 percona-release-x86_64
[root@host-47-106-141-17 ~]# yum install percona-toolkit -y
验证安装是否成功
[root@host-47-106-141-17 ~]# pt-table-checksum --help
[root@host-47-106-141-17 ~]# pt-query-digest --help
三、percona-toolkit命令介绍
3.1 pt-table-checksum常用参数
--nocheck-replication-filters :不检查复制过滤器,建议启用。后面可以用--databases来指定需要检查的数据库。
--no-check-binlog-format : 不检查复制的binlog模式,要是binlog模式是ROW,则会报错。
--replicate-check-only :只显示不同步的信息。
--replicate= :把checksum的信息写入到指定表中,建议直接写到被检查的数据库当中。
--databases= :指定需要被检查的数据库,多个则用逗号隔开。
--tables= :指定需要被检查的表,多个用逗号隔开
h= :Master的地址
u= :用户名
p=:密码
P= :端口
3.2 pt-table-sync常用参数
--replicate= :指定通过pt-table-checksum得到的表,这2个工具差不多都会一直用
--databases= : 指定执行同步的数据库
--tables= :指定执行同步的表,多个用逗号隔开
--sync-to-master :指定一个DNS,即从的IP,他会通过show processlist或show slave status 去自动的找主
h= :服务器地址,命令里有2个ip,第一次出现的是Master的地址,第2次是Slave的地址
u= :帐号
p= :密码
--print :打印,但不执行命令
--execute :执行命令
3.3 pt-hearbeat常用参数
注意:需要指定的参数至少有 --stop,--update,--monitor,--check。
其中--update,--monitor和--check是互斥的,--daemonize和--check也是互斥。
--ask-pass 隐式输入MySQL密码
--charset 字符集设置
--check 检查从的延迟,检查一次就退出,除非指定了--recurse会递归的检查所有的从服务器。
--check-read-only 如果从服务器开启了只读模式,该工具会跳过任何插入。
--create-table 在主上创建心跳监控的表,如果该表不存在,可以自己手动建立,建议存储引擎改成memory。通过更新该表知道主从延迟的差距。
heratbeat 表一直在更改ts和position,而ts是我们检查复制延迟的关键。
--daemonize 执行时,放入到后台执行
--user=-u, 连接数据库的帐号
--database=-D, 连接数据库的名称
--host=-h, 连接的数据库地址
--password=-p, 连接数据库的密码
--port=-P, 连接数据库的端口
--socket=-S, 连接数据库的套接字文件
--file 【--file=output.txt】 打印--monitor最新的记录到指定的文件,很好的防止满屏幕都是数据的烦恼。
--frames 【--frames=1m,2m,3m】 在--monitor里输出的[]里的记录段,默认是1m,5m,15m。可以指定1个,如:--frames=1s,多个用逗号隔开。可用单位有秒(s)、分钟(m)、小时(h)、天(d)。
--interval 检查、更新的间隔时间。默认是见是1s。最小的单位是0.01s,最大精度为小数点后两位,因此0.015将调整至0.02。
--log 开启daemonized模式的所有日志将会被打印到制定的文件中。
--monitor 持续监控从的延迟情况。通过--interval指定的间隔时间,打印出从的延迟信息,通过--file则可以把这些信息打印到指定的文件。
--master-server-id 指定主的server_id,若没有指定则该工具会连到主上查找其server_id。
--print-master-server-id 在--monitor和--check 模式下,指定该参数则打印出主的server_id。
--recurse 多级复制的检查深度。模式M-S-S...不是最后的一个从都需要开启log_slave_updates,这样才能检查到。
--recursion-method 指定复制检查的方式,默认为processlist,hosts。
--update 更新主上的心跳表。
--replace 使用--replace代替--update模式更新心跳表里的时间字段,这样的好处是不用管表里是否有行。
--stop 停止运行该工具(--daemonize),在/tmp/目录下创建一个“pt-heartbeat-sentinel” 文件。后面想重新开启则需要把该临时文件删除,才能开启(--daemonize)。
--table 指定心跳表名,默认heartbeat。
四、pt-table-checksum使用
本次实验:
mysql-master:39.108.217.12
mysql-slave1:47.98.97.124
mysql-slave2:47.106.141.17
4.1 在主库执行授权(一定要对主库ip授权,授权的用户名和密码可以自行定义,不过要保证这个权限能同时登陆主库和从库)
MariaDB [(none)]> grant select,process,super,replication slave,create,delete,insert,update on *.* to 'repsta'@'39.108.217.12' identified by '123456';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)
4.2 在两个从库上执行授权
MariaDB [(none)]> grant select,process,super,replication slave on *.* to 'repsta'@'39.108.217.12' identified by '123456';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)
4.3 在主库上执行的一个检查主从数据一致性的命令
第一次运行:
[root@host-39-108-217-12 ~]# pt-table-checksum --nocheck-replication-filters --no-check-binlog-format --replicate=test.checksums --create-replicate-table --databases=zabbix h=39.108.217.12,u=repsta,p=123456,P=3306
第二次运行:
[root@host-39-108-217-12 ~]# pt-table-checksum --nocheck-replication-filters --no-check-binlog-format --replicate=test.checksums --databases=zabbix h=39.108.217.12,u=repsta,p=123456,P=3306
Checking if all tables can be checksummed ...
Starting checksum ...
TS ERRORS DIFFS ROWS DIFF_ROWS CHUNKS SKIPPED TIME TABLE
07-04T18:07:27 0 0 0 0 1 0 0.295 zabbix.acknowledges
07-04T18:07:27 0 0 5 0 1 0 0.298 zabbix.actions
07-04T18:07:27 0 0 0 0 1 0 0.298 zabbix.alerts
07-04T18:07:27 0 0 0 0 1 0 0.297 zabbix.application_discovery
07-04T18:07:28 0 0 1 0 1 0 0.299 zabbix.application_prototype
注释:
TS :完成检查的时间。
ERRORS :检查时候发生错误和警告的数量。
DIFFS :0表示一致,1表示不一致。当指定--no-replicate-check时,会一直为0,当指定--replicate-check-only会显示不同的信息。
ROWS :表的行数。
CHUNKS :被划分到表中的块的数目。
SKIPPED :由于错误或警告或过大,则跳过块的数目。
TIME :执行的时间。
TABLE :被检查的表名。
4.4 扩展:只显示不同步的信息,打印出来(--replicate-check-only)
[root@host-39-108-217-12 ~]# pt-table-checksum --nocheck-replication-filters --no-check-binlog-format --replicate-check-only --replicate=test.checksums --databases=zabbix h=39.108.217.12,u=repsta,p=123456,P=3306
注:
1.第一次运行的时候需要添加--create-replicate-table参数,后续再运行时就不需要加了
2.如果要对比多个数据库,可以在--databases=a,b,c...用逗号隔开
3.根据测试,需要一个即能登录主库,也能登录从库的账号
4.只能指定一个host,必须为主库的IP
5.在检查时会向表加S锁
6.运行之前需要从库的同步IO和SQL进程是YES状态,如果不是则会报错
五、pt-table-sync使用
pt-table-sync: 高效的同步MySQL表之间的数据,他可以做单向和双向同步的表数据。他可以同步单个表,也可以同步整个库。它不同步表结构、索引、或任何其他模式对象。所以在修复一致性之前需要保证他们表存在。
假如上面检查数据时发现主从不一致
[root@host-39-108-217-12 ~]# pt-table-checksum --nocheck-replication-filters --no-check-binlog-format --replicate=test.checksums --databases=zabbix h=39.108.217.12,u=repsta,p=123456,P=3306
Checking if all tables can be checksummed ...
Starting checksum ...
TS ERRORS DIFFS ROWS DIFF_ROWS CHUNKS SKIPPED TIME TABLE
07-04T18:07:27 0 0 0 0 1 0 0.295 zabbix.acknowledges
07-04T18:07:27 0 0 5 0 1 0 0.298 zabbix.actions
07-04T18:07:27 1 0 0 0 1 0 0.298 zabbix.alerts
现在需要DIFFS为1可知主从数据不一致,需要修复!修复命令如下:
先master的ip,用户,密码,然后是slave的ip,用户,密码
[root@host-39-108-217-12 ~]# pt-table-sync --replicate=test.checksums h=39.108.217.12,u=repsta,p=123456 h=47.106.141.17,u=repsta,p=123456 h=47.98.97.124,u=repsta,p=123456 --print
建议:
1.修复数据的时候,用--print打印出来,这样就可以知道那些数据有问题
2.修复数据之前一定要备份数据库
在上面的操作中,在主库里添加pt-table-checksum检查的权限后,进行数据一致性检查操作,会在操作的库(实例中是test)下产生一个checksums表!
这张checksums表是pt-table-checksum检查过程中产生的。这张表一旦产生了,默认是删除不了的,并且这张表所在的库也默认删除不了,删除后过一会儿就又会出来。
那么如何删除checksums表呢?
MariaDB [(none)]> show grants for 'repsta'@'39.108.217.12';
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Grants for [email protected] |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, PROCESS, SUPER, REPLICATION SLAVE ON *.* TO 'repsta'@'39.108.217.12' IDENTIFIED BY PASSWORD '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
MariaDB [(none)]> revoke SELECT, INSERT, UPDATE, DELETE, CREATE, PROCESS, SUPER, REPLICATION SLAVE ON *.* FROM 'repsta'@'39.108.217.12';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> show grants for 'repsta'@'39.108.217.12';
+-------------------------------------------------------------------------------------------------------------------+
| Grants for [email protected] |
+-------------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'repsta'@'39.108.217.12' IDENTIFIED BY PASSWORD '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' |
+-------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
MariaDB [(none)]> select user,host,password from mysql.user;
+--------+--------------------+-------------------------------------------+
| user | host | password |
+--------+--------------------+-------------------------------------------+
| root | localhost | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 |
| root | host-39-108-217-12 | |
| root | 127.0.0.1 | |
| root | ::1 | |
| | localhost | |
| | host-39-108-217-12 | |
| rep | 47.98.97.124 | *9FF2C222F44C7BBA5CC7E3BE8573AA4E1776278C |
| rep | 47.106.141.17 | *9FF2C222F44C7BBA5CC7E3BE8573AA4E1776278C |
| zabbix | 39.108.217.12 | *DEEF4D7D88CD046ECA02A80393B7780A63E7E789 |
| repsta | 39.108.217.12 | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 |
+--------+--------------------+-------------------------------------------+
10 rows in set (0.00 sec)
MariaDB [(none)]> drop user 'repsta'@'39.108.217.12';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> use test
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MariaDB [test]> show tables;
+----------------+
| Tables_in_test |
+----------------+
| checksums |
+----------------+
1 row in set (0.00 sec)
MariaDB [test]> drop table checksums;
Query OK, 0 rows affected (0.00 sec)
MariaDB [test]> show tables;
Empty set (0.00 sec)
注:主库回收权限。
六、编写监控脚本,当主从数据不一致时,强制修复数据
背景:在当前的示例中,我们主要监控的是zabbix库,当主从不一致时强制修复。当然如果需要监控多个数据库,可以编写多个监控脚本。
思路:计算DIFFS的和值,如果等于0则表示数据一致,如果大于0则表示数据不一致。
[root@host-39-108-217-12 ~]# pt-table-checksum --nocheck-replication-filters --no-check-binlog-format --replicate=test.checksums --databases=zabbix h=39.108.217.12,u=repsta,p=123456,P=3306 | awk 'NR>3{sum+=$3}END{print sum}'
0
扩展计算和值:
sum=0
for i in `cat a.txt`
do
sum=$(($sum+$i))
done
echo $sum
监控脚本:
#!/bin/bash
NUM=`/usr/bin/pt-table-checksum --nocheck-replication-filters --no-check-binlog-format --replicate=test.checksums --databases=zabbix h=39.108.217.12,u=repsta,p=123456,P=3306 | awk 'NR>3{sum+=$3}END{print sum}'`
if [ $NUM -eq 0 ];then
echo "Data is ok!"
else
echo "Data is error!"
/usr/bin/pt-table-sync --replicate=test.checksums h=39.108.217.12,u=repsta,p=123456 h=47.106.141.17,u=repsta,p=123456 h=47.98.97.124,u=repsta,p=123456 --print
/usr/bin/pt-table-sync --replicate=test.checksums h=39.108.217.12,u=repsta,p=123456 h=47.106.141.17,u=repsta,p=123456 h=47.98.97.124,u=repsta,p=123456 --execute
fi
总结:pt-table-checksum和pt-table-sync工具很给力,工作中常常在使用。注意使用该工具需要授权,一般SELECT, PROCESS, SUPER, REPLICATION SLAVE等权限就已经足够了。
七、pt-heartbeat监控mysql主从复制延迟使用
对于MySQL数据库主从复制延迟的监控,可以借助percona的有力武器pt-heartbeat来实现
pt-heartbeat的工作原理通过使用时间戳方式在主库上更新特定表,然后在从库上读取被更新的时间戳然后与本地系统时间对比来得出其延迟。
具体流程:
1.在主上创建一张heartbeat表,按照一定的时间频率更新该表的字段(把时间更新进去)。监控操作运行后,heartbeat表能促使主从同步!
2.连接到从库上检查复制的时间记录,和从库的当前系统时间进行比较,得出时间的差异。
使用方法(主从和从库上都可以执行监控操作)
实例说明:
master:39.108.217.12
slave1:47.106.141.17
slave2:47.98.97.124
同步的库:zabbix
主从库都能使用repsta账号、密码123456登录
先操作针对zabbix库的检查,其他同步的库的检查操作类似!
更新主库上的heartbeat,--interval=1表示1秒钟更新一次(注意这个启动操作要在主库服务器上执行)
1. 主库上的对应库下创建heartbeat表,一般创建后从库会同步这张表(不同步的话,就在从库那边手动也手动创建)
MariaDB [zabbix]> CREATE TABLE heartbeat (
-> ts varchar(26) NOT NULL,
-> server_id int unsigned NOT NULL PRIMARY KEY,
-> file varchar(255) DEFAULT NULL,
-> position bigint unsigned DEFAULT NULL,
-> relay_master_log_file varchar(255) DEFAULT NULL,
-> exec_master_log_pos bigint unsigned DEFAULT NULL
-> );
Query OK, 0 rows affected (0.01 sec)
2.更新主库上的heartbeat,--interval=1表示1秒钟更新一次(注意这个启动操作要在主库服务器上执行)
[root@host-39-108-217-12 scripts]# pt-heartbeat --user=repsta --ask-pass --host=39.108.217.12 --create-table --database zabbix --interval=1 --interval=1 --update --replace --daemonize
Enter password: 123456
[root@host-39-108-217-12 scripts]# ps -ef|grep pt-heartbeat
root 26463 1 0 15:15 ? 00:00:00 perl /usr/bin/pt-heartbeat --user=repsta --ask-pass --host=39.108.217.12 --create-table --database zabbix --interval=1 --interval=1 --update --replace --daemonize
root 26465 26009 0 15:16 pts/0 00:00:00 grep --color=auto pt-heartbeat
3.在主库运行监测同步延迟
[root@host-39-108-217-12 scripts]# pt-heartbeat --database zabbix --table=heartbeat --monitor --host=39.108.217.12 --user=repsta --password=123456 --master-server-id=1
0.00s [ 0.00s, 0.00s, 0.00s ]
0.00s [ 0.00s, 0.00s, 0.00s ]
0.00s [ 0.00s, 0.00s, 0.00s ]
...............................................
注:必须要带上--master-server-id
一次性check出来(--check参数)
[root@host-39-108-217-12 scripts]# pt-heartbeat --database zabbix --table=heartbeat --check --host=39.108.217.12 --user=repsta --password=123456 --master-server-id=1
0.00
如果想输出自动化监控脚本,则最好记录实时的log日志(--log=/opt/master-slave.txt)
[root@host-39-108-217-12 scripts]# pt-heartbeat --database zabbix --table=heartbeat --monitor --host=39.108.217.12 --user=repsta --password=123456 --log=/opt/master-slave.txt --master-server-id=1 --daemonize
注:
1.使用了--check,就不能使用--monit。--update,--monitor和--check是互斥的,--daemonize和--check也是互斥。
2.要测试哪个库,就在哪个库下面创建heartbeat表。
3.如果想把这个输出结果加入自动化监控,那么可以使用如下命令使监控输出写到文件,然后使用脚本定期过滤文件中的最大值作为预警即可:
4.--log选项必须在有--daemonize参数的时候才会打印到文件中,且这个文件的路径最好在/tmp下,否则可能因为权限问题无法创建
监控脚本:
#!/bin/bash
cat /opt/master-slave.txt > /opt/master_slave.txt
max_time=`cat /opt/master_slave.txt | grep -v '^$' | awk '{print $1}' | sort -k 1 -nr | head -1`
NUM=$(echo "$max_time"|cut -d"s" -f1)
if [ $NUM == "0.00" ];then
echo "Mysql主从数据一致"
else
echo "Mysql主从数据不一致"
fi