1.场景说明
本章内容直接上干货,和我一起从0开始编写一个满足自己要求的shell脚本,通过脚本来监控mysql主从同步状态。发送通知邮件给自己,异常状态实时通知。
场景需求如下:
- 通过脚本监控mysql主从库同步状态,获取状态码,错误信息
- 配置可进行自动判断跳过的同步错误码,根据错误码进行异常跳过
- 通过异常状态码监控无法恢复的错误
- 通过不同状态获取错误信息,进行邮件发送
- 配置邮件模板,根据状态码写入不同的通知邮件内容
- 通过定时任务配置脚本执行
- 配置mysql安全登录方式执行命令
- 邮箱发送配置
题外话:本章内容适合和我一样不是专业运维人员的开发人员,记录是为了下一次能够在此基础上更好的编写脚本,实现自己的需求功能,如有运维大大看到,请多多指教,有些内容可能并不完美,但以实现功能需求为第一目的。
2.优先需要了解的技术内容
- shell语法 if for 结构化命令
- shell变量数组使用
- cat mail echo egrep awk 管道 重定向
- mysql主从状态、错误码
3.下面开始我人生中第一个shell脚本
说说以下脚本都实现了什么:
- 获取mysql主从同步状态
- 获取错误信息
- 判断错误进行自动化脚本处理,可以进行部分错误系统自动修正
- 错误信息输出到错误文件
- 根据状态发送邮件到自己邮箱
#!/bin/bash msg="Mysql Slave is Downed" error_code=(1158 1159 1008 1007 1062) mysql_cmd="mysql -u root -pxxx" mha_state=false $mysql_cmd -e "show slave status\G;" |egrep '_Running|Last_SQL'|awk -v FS=":" '{print $N}' > /home/sql_error.txt array=($($mysql_cmd -e "show slave status\G;" |egrep '_Running|Last_SQL_Errno|Last_'|awk '{print $NF}')) if [ "${array[0]}" == "Yes" -a "${array[1]}" == "Yes" -a "${array[2]}" == "0" ] then echo "Mysql Slave is running" else for (( i = 0; i < n; i++ )); do if [ "${array[3]}" == "${error_code[$i]}" ]; then $mysql_cmd -e "stop slave;set global sql_slave_skip_counter=1;start slave;" echo "=========执行自动恢复计划任务执行===========" >> /home/sql_error.txt mail -s "$msg" xxx@qq.com < /home/sql_error.txt cat "" > /home/sql_error.txt $mha_state=true fi done #echo "$msg"|mail -s "$msg" xxx@qq.com if [ "${mha_state}" == "false" ]; then echo "=========异常错误无法进行自动恢复,请尽快登录处理===========" >> /home/sql_error.txt mail -s "$msg" xxx@qq.com < /home/sql_error.txt cat "" > /home/sql_error.txt fi fi
需要优化的部分:
- mysql安全性,密码写在脚本里面不够安全
- 结构混乱功能混杂,需要进行函数编写
- 没有配置定时任务到服务器进行监控(不建议脚本进行死循环sleep这种处理方式)
4.最终使用脚本及配置方式
- 最终脚本
#!/bin/bash PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/local/mysql/bin:/root/bin export PATH msg="Mysql Slave is Downed" error_code=(1158 1159 1008 1007 1062) mysql_cmd="mysql --login-path=pathA" mha_state=false $mysql_cmd -e "show slave status\G;" |egrep '_Running|Last_SQL'|awk -v FS=":" '{print $N}' > /home/sql_error.txt array=($($mysql_cmd -e "show slave status\G;" |egrep '_Running|Last_SQL_Errno|Last_'|awk '{print $NF}')) #这里注意使用的全局变量 function slaveErrorAutomaticRecovery() { for (( i = 0; i < n; i++ )); do if [ "${array[3]}" == "${error_code[$i]}" ]; then $mysql_cmd -e "stop slave;set global sql_slave_skip_counter=1;start slave;" echo "=========执行自动恢复计划任务执行===========" >> /home/sql_error.txt cat /home/sql_error.txt |mail -s "${msg}" 425155363@qq.com >/dev/null cat /dev/null > /home/sql_error.txt mha_state=true fi done } function slaveErrorCannotBeRecovered() { if [ "$1" == "false" ]; then echo "=========异常错误无法进行自动恢复,请尽快登录处理===========" >> /home/sql_error.txt #>/dev/null 加这个是为了不让mail输出到控制台,这玩意一直报Unknown command: "et" 用什么方式都解决交不了 cat /home/sql_error.txt |mail -s "${msg}" 425155363@qq.com >/dev/null cat /dev/null > /home/sql_error.txt fi } if [ "${array[0]}" == "Yes" -a "${array[1]}" == "Yes" -a "${array[2]}" == "0" ] then echo "Mysql Slave is running" else slaveErrorAutomaticRecovery slaveErrorCannotBeRecovered $mha_state fi
- mysql安全登录设置
#设置登录 mysql_config_editor set --login-path=pathA --host=localhost --user=root --password --port=3306 #登录 mysql --login-path=pathA #重置 mysql_config_editor reset #打印配置信息 mysql_config_editor print --all
5.配置定时任务做守护进程定时执行
crontab -e #这里有什么问题记得找百度 * */1 * * * /bin/bash /home/mysql_mha.sh