實時檢測mysql主從狀態,並作郵件告警python
需求分析:mysql
當咱們作完主從後,主從成功的話,Slave_IO_Running和Slave_SQL_Running兩個進程的狀態就爲yes,可是在作主從同步時也不排除,會發生一些意外的狀況,因此咱們須要寫個腳原本實時檢測Slave_IO_Running和Slave_SQL_Running的狀態,一旦mysql主從狀態出現了情況,就經過郵件發送告警,而後再作維護。sql
腳本思路:bash
定時檢測mysql主從狀態,說白的了就是經過腳本讓系統去自我檢測主從狀態,若是是主從狀態是正常的,那就不作告警出來,但一旦發生狀態異常,就經過發送郵件給運維人員,運維人員收到告警郵件後,而後就作相關的維護處理服務器
一、郵件告警,我直接用的是Python寫的腳本作郵件信息發送,你也能夠yum裝個sendmail包,作信息發送,腳本以下。運維
[root@mysqlslave ~]# cd /python/send_mail.py #!/usr/bin/python #coding: utf-8 import smtplib import sys from email.mime.text import MIMEText _user = "847536**@qq.com" ##這裏填寫你的郵件號 _pwd = "ilbsly******" ##這裏填寫你郵件的密碼 ,我這裏使用的是qq郵箱(其餘郵箱也能夠),qq郵箱密碼是要到QQ郵箱裏面申請的,而後它會生成一個密碼的 #_to = "dsf@163.com" ##這裏是發送給誰,這個通常註釋掉,在執行腳本的時候指定發給誰就能夠了 def send_mail(to,subject,contain): msg = MIMEText(contain) msg["Subject"] = subject msg["From"] = _user msg["To"] = to try: s = smtplib.SMTP_SSL("smtp.qq.com", 465) s.login(_user, _pwd) s.sendmail(_user, to, msg.as_string()) s.quit() with open('/tmp/zabbix.log', 'w') as f: f.write("%s\n%s\n%s\n"%(to,subject,contain)) # print "Success!" except smtplib.SMTPException,e: print "Falied,%s"%e if __name__ == "__main__": send_mail(sys.argv[1], sys.argv[2], sys.argv[3])
二、檢測腳本編寫tcp
接下來,寫個檢測主從腳本,按照咱們的思路來講,首先是把Slave_IO_Running和Slave_SQL_Running的狀態獲取,而後利用if語句判斷,若是狀態爲NO就經過Python腳原本發送郵件,嚴重一點的,若是從服務器的MySQL服務down了,咱們也發送郵件告警,把整個過程執行過程,寫的時間任務裏面,這裏咱們須要使用函數來實現,這個方便快捷,接下來我詳細解析。ide
[root@mysqlslave ~]# cd /python/checkslave.sh #!/bin/bash send_mail (){ ##定義一個函數,用來作整合檢測MySQL狀態內容。 ip=`ifconfig eth0 | sed -n 2p | awk '{print $2}' | cut -d: -f2` ##獲取本地的ip,個人本地網卡爲eth0,使用sed、awk、cut命令獲取IP地址 hostname=`hostname` ##獲取本地的主機名 status=(`mysql -uroot -pmichael123456 -e "show slave status\G"|grep "Running" |awk '{print $2}'`) ##經過MySQL命令獲取Slave_IO_Running和Slave_SQL_Running的狀態,獲取出來的結果是(Yes、Yes、slave),由於有三個元素,因此咱們可使用元組來實現 netstat -ntpl | grep 3306 ##查看3306是否存在,用來作檢測MySQL的狀態 if [ $? -eq 0 ];then ##寫一個判斷語句若是netstat命令執行成功話,輸出$?是0,不存在$?輸出結果大於0 if [ "${status[0]}" == "Yes" ] || [ "${status[1]}" == "Yes" ] ;then ##獲取元組的第零個元素數和第一個元素,使用if判斷,採用並集。 echo "主從複製成功" else ##作個判斷 python /python/send_mail.py "847536944@qq.com" "$hostname:$ip-主從複製失敗" "$hostname:$ip- Slave_IO_Running 或者 Slave_SQL_Running已經爲NO請儘快:作維護處理" ##當輸出的元組的結果不爲Yes,而後就執行,郵件發送告警$hostname 、$ip爲獲取的參數 sed -i 's/^*\/10/#&/g' /etc/crontab ##爲了防止,它一直在郵件告警,咱們須要用sed註釋掉,計劃任務,這個的做用就是隻容許發送故障後, #腳本只執行一次,固然,若是你想發兩封的郵件,你也能夠添加發送郵件命令兩遍。 fi else python /python/send_mail.py "847536944@qq.com" "$hostname:$ip-slave主機mysql服務已經關閉" "$hostname:$ip-主機已經中止運行請儘快作維護" ##netstat輸出$?的結果不爲0,發送告警。 fi } $1 ##添加函數的參數,讓本身決定是否執行該函數 crontab () { cat /etc/crontab | grep "bash $0 send_mail " ##查找是否有計劃任務 if [ $? -eq 0 ]; then ##作判斷,有就輸出有,沒有就寫入 echo "The port test has been written to the time task" else echo "*/10 * * * * root bash $0 send_mail " >> /etc/crontab ##定義每十分鐘,執行一次 fi } crontab
三、執行結果函數
[root@mysqlslave ~]# bash /python/checkslave.sh #執行第一次,查看不了效果
##經過函數來執行,能夠發現,已經有效果了,ui
[root@mysqlslave ~]# bash /python/checkslave.sh send_mail Warning: Using a password on the command line interface can be insecure. tcp 0 0 :::3306 :::* LISTEN 27684/mysqld 主從複製成功 */10 * * * * root bash /python/checkslave.sh send_mail The port test has been written to the time task
四、模擬故障
我把slave停掉了,等了幾分鐘後,已經能夠收到郵件了,結果以下:
五、總結
感受寫了個腳本後,發現已經不用每隔一段時刻要本身檢測slave的狀態了。方便了不少,固然,還有別的方法,也一樣能夠的作主從複製狀態監控。