如何實時檢測mysql主從狀態,並做郵件告警?

                                                      實時檢測mysql主從狀態,並做郵件告警

 需求分析:

    當我們做完主從後,主從成功的話,Slave_IO_Running和Slave_SQL_Running兩個進程的狀態就爲yes,但是在做主從同步時也不排除,會發生一些意外的情況,所以我們需要寫個腳本來實時檢測Slave_IO_Running和Slave_SQL_Running的狀態,一旦mysql主從狀態出現了狀況,就通過郵件發送告警,然後再做維護。

 

 腳本思路:

   定時檢測mysql主從狀態,說白的了就是通過腳本讓系統去自我檢測主從狀態,如果是主從狀態是正常的,那就不做告警出來,但一旦發生狀態異常,就通過發送郵件給運維人員,運維人員收到告警郵件後,然後就做相關的維護處理

 

 1、郵件告警,我直接用的是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   = "[email protected]"    ##這裏是發送給誰,這個一般註釋掉,在執行腳本的時候指定發給誰就可以了
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])


2、檢測腳本編寫

   接下來,寫個檢測主從腳本,按照我們的思路來說,首先是把Slave_IO_Running和Slave_SQL_Running的狀態獲取,然後利用if語句判斷,如果狀態爲NO就通過Python腳本來發送郵件,嚴重一點的,如果從服務器的MySQL服務down了,我們也發送郵件告警,把整個過程執行過程,寫的時間任務裏面,這裏我們需要使用函數來實現,這個方便快捷,接下來我詳細解析。

[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 "[email protected]" "$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 "[email protected]" "$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




3、執行結果

[root@mysqlslave ~]# bash /python/checkslave.sh   #執行第一次,查看不了效果

##通過函數來執行,可以發現,已經有效果了,

[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

4、模擬故障

我把slave停掉了,等了幾分鐘後,已經可以收到郵件了,結果如下:

blob.png



5、總結

  感覺寫了個腳本後,發現已經不用每隔一段時刻要自己檢測slave的狀態了。方便了很多,當然,還有別的方法,也同樣可以的做主從複製狀態監控。

  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章