Mysql監控屬於DB監控的模塊之一,包括采集、展示、監控告警。本文主要介紹Mysql監控的主要指標和采集方法。
Mysql監控和Redis監控的邏輯類似,可參考文章《Redis監控》。
DBA前台添加Mysql監控時系統會調用自動調度平台接口將Mysql監控的加密賬戶密碼和ip端口等信息發送至目標,同時發送采集Agent。
一、采集指標和命令
1、Mysql服務運行狀態
約定所有Mysql服務都必須以ip1(內網ip)來綁定,每個機器只有一個ip1,可以有多個端口,即多個Mysql Server。采集程序讀取ip端口信息文件來判斷server是否存在。
sockParam=`ps aux | grep -P "mysqld.*--port=${port}" | grep -oP " --socket.*\.sock"` # 空則獲取不到該服務器端口mysql socket配置,請檢查mysql配置是否正確 MYSQL="/usr/local/mysql/bin/mysql -hlocalhost --port=${port} ${sockParam} -u${user} -p${password} " MYSQL_ADMIN="/usr/local/mysql/bin/mysqladmin -hlocalhost --port=${port} ${sockParam} -u${user} -p${password} " curStatus=`${MYSQL} -e"show global status"` # 空則是獲取不到該服務器mysql狀態,請檢查mysql是否正常運行 if [ -z "${curStatus}" ] then portExists=0 else echo "${curStatus}" >> ${curFile} portExists=1
2、連接數
${MYSQL_ADMIN} processlist -v | wc -l
3、線程數
grep 'Threads_connected' ${curFile} | awk '{print $2}'
4、慢查詢數
grep 'Slow_queries' ${curFile} | awk -F ' ' '{print $2}'
需要計算兩次的慢查詢次數得到差值,等於最近1分鐘的慢查詢次數。上次數據保存在last.cache。
5、打開表數
grep 'Open_tables' ${curFile} | awk -F ' ' '{print $2}'
6、每秒執行select數
grep 'Com_select' ${curFile} | awk -F ' ' '{print $2}'
需要計算兩次的慢查詢次數得到差值除以時間差,等於最近1分鐘的執行數量。上次數據保存在last.cache。
7、每秒執行delete數
grep 'Com_delete' ${curFile} | grep -v 'multi' | awk -F ' ' '{print $2}'
需要計算兩次的慢查詢次數得到差值除以時間差,等於最近1分鐘的執行數量。上次數據保存在last.cache。
8、每秒執行insert數
grep 'Com_insert' ${curFile} | grep -v 'select' | awk -F ' ' '{print $2}'
需要計算兩次的慢查詢次數得到差值除以時間差,等於最近1分鐘的執行數量。上次數據保存在last.cache。
9、每秒執行update數
grep 'Com_update' ${curFile} | grep -v 'multi' | awk -F ' ' '{print $2}'
需要計算兩次的慢查詢次數得到差值除以時間差,等於最近1分鐘的執行數量。上次數據保存在last.cache。
10、每秒鐘執行replace數
grep 'Com_replace' ${curFile} | grep -v 'select' | awk -F ' ' '{print $2}'
需要計算兩次的慢查詢次數得到差值除以時間差,等於最近1分鐘的執行數量。上次數據保存在last.cache。
11、每秒鐘執行的 Innodb_rows_deleted
grep 'Innodb_rows_deleted' ${curFile} | awk -F ' ' '{print $2}'
需要計算兩次的慢查詢次數得到差值除以時間差,等於最近1分鐘的執行數量。上次數據保存在last.cache。
12、每秒鐘執行的 Innodb_rows_inserted
grep 'Innodb_rows_inserted' ${curFile} | awk -F ' ' '{print $2}'
需要計算兩次的慢查詢次數得到差值除以時間差,等於最近1分鐘的執行數量。上次數據保存在last.cache。
13、每秒鐘執行的 Innodb_rows_read
grep 'Innodb_rows_read' ${curFile} | awk -F ' ' '{print $2}'
需要計算兩次的慢查詢次數得到差值除以時間差,等於最近1分鐘的執行數量。上次數據保存在last.cache。
14、每秒鐘執行的 Innodb_rows_updated
grep 'Innodb_rows_updated' ${curFile} | awk -F ' ' '{print $2}'
需要計算兩次的慢查詢次數得到差值除以時間差,等於最近1分鐘的執行數量。上次數據保存在last.cache。
15、每秒鐘執行的 innodb rows total
expr ${innodbRowsDeletedPS} + ${innodbRowsInsertedPS} + ${innodbRowsReadPS} + ${innodbRowsUpdatedPS}
等於前面四個Innodb_rows_*執行次數的總和
16、每秒處理命令數 qps
expr ${mysqlSelectNumPS} + ${mysqlInsertNumPS} + ${mysqlUpdateNumPS} + ${mysqlDeleteNumPS} + ${mysqlReplaceNumPS}
等於前面五個mysql命令Com_*的數量總和
17、每秒接收字節數 KByte/s
grep 'Bytes_received' ${curFile} | awk -F ' ' '{print $2}'
需要計算兩次的慢查詢次數得到差值除以時間差,等於最近1分鐘的執行數量,除以1024得到單位KByte/s。上次數據保存在last.cache。
18、每秒發送字節數
grep 'Bytes_sent' ${curFile} | awk -F ' ' '{print $2}'
需要計算兩次的慢查詢次數得到差值除以時間差,等於最近1分鐘的執行數量,除以1024得到單位KByte/s。上次數據保存在last.cache。
19、可立即獲得鎖的次數
grep 'Table_locks_immediate' ${curFile} | awk -F ' ' '{print $2}'
需要計算兩次的慢查詢次數得到差值,等於最近1分鐘的可立即獲得鎖數量。上次數據保存在last.cache。
20、不可立即獲得鎖的次數
grep 'Table_locks_waited' ${curFile} | awk -F ' ' '{print $2}'
需要計算兩次的慢查詢次數得到差值,等於最近1分鐘的不可立即獲得鎖數量。上次數據保存在last.cache。
21、一行鎖定需等待時間
grep 'Innodb_row_lock_waits' ${curFile} | awk -F ' ' '{print $2}'
需要計算兩次的慢查詢次數得到差值,等於最近1分鐘的一行鎖定需等待時間。上次數據保存在last.cache。
22、 當前髒頁數
grep 'Innodb_buffer_pool_pages_dirty' ${curFile} | awk -F ' ' '{print $2}'
23、要求清空的緩沖池頁數
grep 'Innodb_buffer_pool_pages_flushed' ${curFile} | awk -F ' ' '{print $2}'
需要計算兩次的慢查詢次數得到差值,等於最近1分鐘的要求清空的緩沖池頁數。上次數據保存在last.cache。
24、Innodb 寫入日志字節數 KByte
grep 'Innodb_os_log_written' ${curFile} | awk -F ' ' '{print $2}'
需要計算兩次的慢查詢次數得到差值,等於最近1分鐘的寫入日志字節數,除以1024得到KByte。上次數據保存在last.cache。
25、占用內存大小 MByte
pid=`ps aux | grep 'mysqld' | grep -Ev 'safe|grep' | awk '{print $2}' ` mem=`cat /proc/${pid}/status | grep 'VmRSS' | awk '{print $2}'` mysqlMem=`echo "scale=2;${mem} / 1024" | bc`
除以1024得到MByte
26、handler socket每秒處理數
curHsTableLock=`grep 'Hs_table_lock' ${curFile} | awk '{print $2}'` preHsTableLock=`grep 'Hs_table_lock' ${preFile} | awk '{print $2}'` if [ -n "${curHsTableLock}" ] then hsQPS=`echo "scale=0;(${curHsTableLock} - ${preHsTableLock}) / ${intervalTime}" | bc` else hsQPS=0 fi
27、主從同步和狀態
#主從信息 #是否為從服務器 slave_running=`grep 'Slave_running' ${curFile} | awk '{print $2}'` if [ "${slave_running}A" = "ONA" ] then slaveRunning=1 slaveStatus=`${MYSQL} -e'show slave status\G'` echo "${slaveStatus}" > ${slaveFile} slaveIoRunning=`grep 'Slave_IO_Running' ${slaveFile} | awk -F ':' '{print $2}'` slaveSqlRunning=`grep 'Slave_SQL_Running' ${slaveFile} | awk -F ':' '{print $2}'` if [ "${slaveIoRunning}A" == "NoA" -o "${slaveSqlRunning}A" == "NoA" ] then slaveRunning=3 fi secondsBehindMaster=`grep 'Seconds_Behind_Master' ${slaveFile} | awk -F ':' '{print $2}'` if [ "${secondsBehindMaster}A" = "NULLA" ] then secondsBehindMaster=8888 # 表示主從不同步 fi #是從庫時 獲取主庫ip master=`grep 'Master_Host' ${slaveFile} | awk -F ':' '{print $2}'` masterPort=`grep 'Master_Port' ${slaveFile} | awk -F ':' '{print $2}'` else master="" masterPort="" slaveRunning=0 secondsBehindMaster=10000 # 不用檢測 fi
注:Seconds_Behind_Master,該值作為判斷主從延時的指標,那麼它又是怎麼得到這個值的呢,同時,它為什麼又受到很多人 的質疑? (本段引用自 http://blog.chinaunix.net/uid-27038861-id-3686311.html)
Seconds_Behind_Master是通過比較sql_thread執行的event的timestamp和io_thread復制好的 event的timestamp(簡寫為ts)進行比較,而得到的這麼一個差值。我們都知道的relay-log和主庫的bin-log裡面的內容完全一樣,在記錄sql語句的同時會被記錄上當時的ts,所以比較參考的值來自於binlog,其實主從沒有必要與NTP進行同步,也就是說無需保證主從時鐘的 一致。你也會發現,其實比較真正是發生在io_thread與sql_thread之間,而io_thread才真正與主庫有關聯,於是,問題就出來了, 當主庫I/O負載很大或是網絡阻塞,io_thread不能及時復制binlog(沒有中斷,也在復制),而sql_thread一直都能跟上 io_thread的腳本,這時Seconds_Behind_Master的值是0,也就是我們認為的無延時,但是,實際上不是,你懂得。這也就是為什 麼大家要批判用這個參數來監控數據庫是否發生延時不准的原因,但是這個值並不是總是不准,如果當io_thread與master網絡很好的情況下,那麼 該值也是很有價值的。
之前,提到 Seconds_Behind_Master這個參數會有負值出現,我們已經知道該值是io_thread的最近跟新的ts與sql_thread執行到 的ts差值,前者始終是大於後者的,唯一的肯能就是某個event的ts發生了錯誤,比之前的小了,那麼當這種情況發生時,負值出現就成為可能。
28、檢測采集Agent心跳情況
原創文章,轉載請備注原文地址 http://www.cnblogs.com/lxmhhy/p/6034609.html
知識交流討論請加qq:1130010617。謝謝合作。