主从复制其实是很脆弱的,有很多种情况都会导致主从关系停止,比如,我们设置了只同步某个库的数据,如果以后有其他数据库的加入,那么这个主从关系就会造成影响而停止;比如我们在从库中写入数据;主从复制过程中主库宕机了;主库的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.0mysql_cmd="mysql -uroot -proot"errorno=(1158 1159 1008 1007 1062)while truedoarray=($(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" ]thenecho "MySQL is slave is ok"elsefor ((i=0;i<${#errorno[*]};i++))doif [ "${array[3]}" = "${errorno[$i]}" ];then$mysql_cmd -e "stop slave &&set global sql_slave_skip_counter=1;start slave;"fidonecurl 'https://oapi.dingtalk.com/robot/send?access_token=0307673dfab8dc1cffc6a404913a077dcc9163c19318b3c977c70327aff2072b' \-H 'Content-Type: application/json' \-d '{"msgtype": "text","text": {"content": "MySQL slave is not ok"}}'breakfisleep 20done
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
