运维派 企业面试题1 监控MySQL主从同步是否异常
Linux运维必会的实战编程笔试题(19题)
企业面试题1:(生产实战案例):监控MySQL主从同步是否异常,如果异常,则发送短信或者邮件给管理员。提示:如果没主从同步环境,可以用下面文本放到文件里读取来模拟:
阶段1:开发一个守护进程脚本每30秒实现检测一次。
阶段2:如果同步出现如下错误号(1158,1159,1008,1007,1062),则跳过错误。
阶段3:请使用数组技术实现上述脚本(获取主从判断及错误号部分)
#假设文件为/log/test/mysql/err
#假设错误为: error:1120:...
#!/bin/bash # #监控MySQL主从同步是否异常,如果异常,则发送短信或者邮件给管理员。提示:如果没主从同步环境,可以用下面文本放到文件里读取来模拟: #阶段1:开发一个守护进程脚本每30秒实现检测一次。 #阶段2:如果同步出现如下错误号(1158,1159,1008,1007,1062),则跳过错误。 #阶段3:请使用数组技术实现上述脚本(获取主从判断及错误号部分) #假设文件为/log/test/mysql/err #假设错误为: error:1120:... # #version 0.1 # errlocate='/log/test/mysql/err' declare -a errnums declare -i j=0 function msgbox(){ echo "MySQL error number is $1" | mail -s mysql.error.alert root } while true; do if [ `grep 'error:[[:digit:]]\+:' ${errlocate}` ];then for i in `grep -o 'error:[[:digit:]]\+:' ${errlocate} | grep -o '[[:digit:]]\+'` ; do errnums[$j]=$i; case ${errnums[$j]} in 1158) continue;; 1159) continue;; 1008) continue;; 1007) continue;; 1062) continue;; *);; esac #echo "mysql.errnums=${errnums[$j]}" 测试用 msgbox ${errnums[$j]} let j++ #echo "j=$j" 测试用 done #echo "it should be sleeped" 测试用 sleep 30s j=0 else sleep 30s #没有报错就直接等待30s fi done
后台运行之:
-113-[root@vm]18:25 /tmp/sh # chmod -x ywtest1.sh -114-[root@vm]18:26 /tmp/sh # .ywtest1.sh &
不过这个办法并不绝对可靠, 再使用pstree命令时, 自动退出了:
使用 crontab -e创建守护进程, 同时也要取消源代码中的while循环
参考:
linux crontab & 每隔10秒执行一次
-115-[root@vm]18:25 /tmp/sh # crontab -e * * * * * /bin/bash /tmp/sh/ywtest1.sh * * * * * sleep 30s;/bin/bash /tmp/sh/ywtest1.sh
看一下执行效果:
每分钟两封邮件, 即30s一封
但是, 这样会产生一个问题, 当有多个错误码时, 每个错误码都会发一封邮件, 而其本身就是30s执行一次, 所以应该把一次执行的报错结果, 集中到一封邮件中;
解决办法: 修正msgbox函数, 直接输出errnums数组, 不需要参数;
输出数组问题: case屏蔽掉的也会输出出来, 原因在于先赋值给数组后进行筛选
解决办法: 改变赋值次序;
最终版本:
#!/bin/bash # #监控MySQL主从同步是否异常,如果异常,则发送短信或者邮件给管理员。提示:如果没主从同步环境,可以用下面文本放到文件里读取来模拟: #阶段1:开发一个守护进程脚本每30秒实现检测一次。 #阶段2:如果同步出现如下错误号(1158,1159,1008,1007,1062),则跳过错误。 #阶段3:请使用数组技术实现上述脚本(获取主从判断及错误号部分) #文件为/log/test/mysql/err #错误为: error:1120:... # #version 0.1 # errlocate='/log/test/mysql/err' declare -a errnums declare -i j=0 function msgbox(){ echo "MySQL error number is ${errnums[@]}" | mail -s mysql.error.alert root } #删掉while if grep 'error:[[:digit:]]\+:' ${errlocate};then for i in `grep -o 'error:[[:digit:]]\+:' ${errlocate} | grep -o '[[:digit:]]\+'` ; do case $i in #改变赋值给数组的次序 1158) continue;; 1159) continue;; 1008) continue;; 1007) continue;; 1062) continue;; *);; esac #echo "mysql.errnums=${errnums[$j]}" errnums[$j]=$i; let j++ #echo "j=$j" done #echo "it should be sleeped" msgbox #取消参数传递, 直接使用数组输出 sleep 30s j=0 else sleep 30s #没有报错就直接等待30s fi
DONE, 后续敬请期待!