【MySQL】常用監控指標及監控方法
對之前生產中使用過的MySQL資料庫監控指標做個小結。
指標分類 | 指標名稱 | 指標說明 |
效能類指標 | QPS | 資料庫每秒處理的請求數量 |
TPS | 資料庫每秒處理的事務數量 | |
併發數 | 資料庫例項當前並行處理的會話數量 | |
連線數 | 連線到資料庫會話的數量 | |
快取命中率 | 查詢命中快取的比例 | |
高可用指標 | 可用性 | 資料庫是否可以正常對外服務 |
阻塞 | 當前阻塞的會話數 | |
慢查詢 | 慢查詢情況 | |
主從延遲 | 主從延遲時間 | |
主從狀態 | 主從鏈路是否正常 | |
死鎖 | 檢視死鎖資訊 |
【QPS 指標】
show global status where variable_name in ('Queries', 'uptime');
QPS = (Queries2 -Queries1) / (uptime2 - uptime1)
【TPS指標】
show global status where variable_name in ('com_insert' , 'com_delete' , 'com_update', 'uptime');
事務數TC ≈'com_insert' , 'com_delete' , 'com_update'
TPS ≈ (TC2 -TC1) / (uptime2 - uptime1)
【併發數】
show global status like ' Threads_running ';
【連線數】
當前連線數:
show global status like 'Threads_connected';
最大連線數:
show global status like 'max_connections';
生產中配置報警閾值:Threads_connected / max_connections > 0.8
【快取命中率】
innodb緩衝池查詢總數:
show global status like 'innodb_buffer_pool_read_requests';
innodb從磁碟查詢數:
show global status like 'innodb_buffer_pool_reads';
生產中配置報警閾值: (innodb_buffer_pool_read_requests - innodb_buffer_pool_reads) / innodb_buffer_pool_read_requests > 0.95
【可用性】
方法1:週期性連線資料庫並執行 select @@version;
方法2:mysqladmin -u資料庫使用者名稱 -p資料庫密碼 -h資料庫例項IP ping
【阻塞】
MySQL5.7之前:
select b.trx_mysql_thread_id as '被阻塞執行緒', b.trx_query as '被阻塞SQL', c.trx_mysql_thread_id as '阻塞執行緒', c.trx_query as '阻塞SQL', (unix_timestamp()-unix_timestamp(c.trx_started)) as '阻塞時間' from information_schema.innodb_lock_waits a join information_schema.innodb_trx b on a.requesting_trx_id=b.trx_id join information_schema.innodb_trx c on a.blocking_trx_id=c.trx.id where(unix_timestamp()-unix_timestamp(c.trx_started))>阻塞秒數
MySQL5.7及之後:
為方便查詢阻塞指標,MySQL將2張表join構造了一個view sys.innodb_lock_waits ,查詢語句得以大大簡化。
select waiting_pid as '被阻塞執行緒', waiting_query as '被阻塞SQL', blocking_pid as '阻塞執行緒', blocking_query as '阻塞SQL', wait_age as '阻塞時間', sql_kill_blocking_query as '建議操作' from sys.innodb_lock_waits where(unix_timestamp()-unix_timestamp(wait_started))>阻塞秒數
【慢查詢】
方法1:開啟慢查詢日誌 。 my.inf
slow_query_log=on slow_query_log_file=存放目錄 long_query_time=0.1秒 log_queries_not_using_indexes=on
注:只對新建連線生效,實時生效使用命令set global 上述配置項。
方法2:
select * from information_schema.'processlist';
【主從延遲】
方法1:
show slave status;
問題:
該方法是基於relaylog的時間與master的時間差值,並不太準, 例如大事務時,主從延時已發生,但 relaylog還未生成。
方法2:使用Percona的pt-heartbeat工具
- Master後臺週期寫入:
pt-heartbeat --user=Master使用者名稱 --password=Master密碼 --h MasterIP --create-table --database 測試庫名 --updatte --daemonize --interval=1
--create-table 在Master上建立心跳監控表heartbeat,通過更新該表知道主從延遲的差距。建議儲存引擎改成memory。
--daemonize 後臺執行。
--interval=1 預設1秒執行一次。
- Slave後臺週期同步讀取:
pt-heartbeat --user=Slave使用者名稱 --password=Slave密碼 --h SlaveIP --database 庫名 --monitor --daemonize --log /slave_lag.log
--monitor引數是持續監測並輸出結果
【主從狀態】
show slave status;
【死鎖】
方法1:檢視最近一次死鎖資訊:
show engine innodb status;
方法2:使用Percona的pt-deadlock-logger工具
1.開啟死鎖列印全域性開關
set global innodb_print_all_deadlocks=on;
2.使用pt-deadlock-logger工具
監控到的死鎖結果可以輸出到檔案、指定表、或者介面列印。
pt-deadlock-logger h=資料庫IP,u=資料庫使用者名稱,p=資料庫密碼
輸出結果非常詳盡:
server:資料庫伺服器地址,即死鎖產生的資料庫主機
ts:檢測到死鎖的時間戳
thread:產生死鎖的執行緒id,這個id和show processlist裡面的執行緒id是一致的
txn_id:innodb的事務ID
txd_time:死鎖檢查到前,事務執行時間
user:執行transcation的使用者名稱
hostname:客戶端主機名
ip:客戶端ip
db:發生死鎖的DB名
tbl:死鎖發生的表名
idx:產生死鎖的索引名(在上面這個demo裡面, 我們直接走的主鍵,加的記錄鎖)
lock_type:鎖的型別(記錄鎖,gap鎖,next-key鎖)
lock_mode:鎖模式(S,X)
wait_hold:是否等著鎖釋放,一般死鎖都是兩個wait
victim:該會話是否做了犧牲,終止了執行
query:造成死鎖的SQL語句