主从复制其实是很脆弱的,有很多种情况都会导致主从关系停止,比如,我们设置了只同步某个库的数据,如果以后有其他数据库的加入,那么这个主从关系就会造成影响而停止;比如我们在从库中写入数据;主从复制过程中主库宕机了;主库的max_allowed_packet参数比从库大,一个较大的SQL语句在从库上无法执行。
上面这些因素都有可能导致主从关系的停止,因此设置一个主从关系的监控是很有必要的。
主从复制监控Shell脚本
这个脚本的基本思想是过滤含有”_Running”,”Behind_Master”字段的状态,如果发现与预期的不一致就报警。
Slave_IO_Running: Yes Slave_SQL_Running: Yes Seconds_Behind_Master: 0 Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
#!/bin/bash
#Date:2022-01-10
#Author:qinxi
#version 1.0
mysql_cmd="mysql -uroot -proot"
errorno=(1158 1159 1008 1007 1062)
while true
do
array=($(mysql -urep1 -proxe-walle.t -e "show slave status\G;"|egrep "_Running|Behind_Master"|awk '{print $NF}'))
if [ "${array[0]}" == "Yes" -a "${array[1]}" == "Yes" -a "${array[2]}" == "0" ]
then
echo "MySQL is slave is ok"
else
for ((i=0;i<${#errorno[*]};i++))
do
if [ "${array[3]}" = "${errorno[$i]}" ];then
$mysql_cmd -e "stop slave &&set global sql_slave_skip_counter=1;start slave;"
fi
done
curl 'https://oapi.dingtalk.com/robot/send?access_token=0307673dfab8dc1cffc6a404913a077dcc9163c19318b3c977c70327aff2072b' \
-H 'Content-Type: application/json' \
-d '{"msgtype": "text",
"text": {
"content": "MySQL slave is not ok"
}
}'
break
fi
sleep 20
done
MySQL从库从主库上复制binlog文件内容到本地执行,在binlog上命令以event的形式存在,并非一个命令对应一个event。
以一个insert语句为例(引擎InnoDB、binglog_format=statement), 在binlog中实际上有三个event,分别为begin\insert\commit 。 命令类型都是Query_log_event,而set global sql_slave_skip_counter=N的意思,即为在start slave时,从当前位置起,跳过N个event,每跳过一个event,则N—。
如果当前的执行位置是某个insert语句开头,那使用 N=1实际上是从begin\insert\commit的第二个开始执行,这个insert语句还是不能被跳过?
实际上这里还有两个策略:
1、若N=1且当前event为BEGIN, 则N不变,跳过当前event继续。
2、若N=1且当前event处于一个事务之内(BEGIN之后,COMMIT之前),则N不变,跳过当前event继续。
说明:其实上面两个策略合起来就是一句话,当N=1时,会连续跳过若干个event,直到当前所在的事务结束。当然如果N>1,则每跳过一个event都要N—.
定时任务
$ crontab -l
*/15 * * * * bash /data/shell/monitor-mysql.sh >>/tmp/mysql.log