MySQL監控
MySQL可用性監控
- MySQL服務存活監控
- MySQL復制是否終止,延遲多大
- 其它,比如磁盤空間消耗
MySQL性能監控
- 每秒活躍DML數/事務數/請求數/當前並發連接/平均響應時長
- 數據庫吞吐量(收、發字節數)
- 鎖:表鎖,行鎖。鎖等待。死鎖
- 內存:buffer/cache命中率、等待釋放
- 事務:事務ID增長率,unpurged歷史事務
- 慢查詢:平均耗時。平均次數
查看MySQL連接數、當前並發連接、最大連接。
mysql> show status like ‘Threads%‘;
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Threads_cached | 58 |
| Threads_connected | 57 | ###這個數值指的是打開的連接數
| Threads_created | 3676 |
| Threads_running | 4 | ###這個數值指的是激活的連接數,這個數值一般遠低於connected數值
+-------------------+-------+
Threads_connected 跟show processlist結果同樣,表示當前連接數。 準確的來說,Threads_
running是代表當前並發數
這是是查詢數據庫當前設置的最大連接數
mysql> show variables like ‘%max_connections%‘;
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 1000 |
+-----------------+-------+
假設我們在MySQLserver配置文件裏設置了thread_cache_size,當客戶端斷開之後,server處理此客戶的線程將會緩存起來以響應下一個客戶而不是銷毀(前提是緩存數未達上限)。
Threads_created表示創建過的線程數。假設發現Threads_created值過大的話,表明MySQLserver一直在創建線程,這也是比較耗資源。能夠適當添加配置文件裏thread_cache_size值。查詢server
thread_cache_size配置:
1mysql> show variables like ‘thread_cache_size‘;
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| thread_cache_size | 64 |
+-------------------+-------+
show processlist; 能夠顯示前100條連接信息
show full processlist; 能夠顯示所有。
順便說下,假設用普通賬號登錄,就僅僅顯示這用戶的。
鎖等待
"root@localhost:mysql.sock [(none)]>show status like ‘Innodb_row_lock%‘;
+-------------------------------+-------+
| Variable_name | Value |
+-------------------------------+-------+
| Innodb_row_lock_current_waits | 0 |
| Innodb_row_lock_time | 0 |
| Innodb_row_lock_time_avg | 0 |
| Innodb_row_lock_time_max | 0 |
| Innodb_row_lock_waits | 0 |
+-------------------------------+-------+
Innodb_row_lock_current_waits:當前等待的待鎖定的數目(鎖的數量,不是鎖定的行的數量)。
Innodb_row_lock_waits:一行鎖定必須等待的總時長
Table_locks_waited:表鎖等待次數
死鎖的話,須要找到兩條SQL所在的事務。否則基本上無法排查出為什麽會有死鎖。偶爾有死鎖能夠,僅僅要不是太頻繁。
更關鍵的是當前行鎖發生的次數,以及當前行鎖等待發生的次數。
buffer/cache命中率一般99%以上。
更重要的是看內存夠不夠用。
怎麽看內存夠不夠用呢?看內存等待釋放的指標是不是大於0。Innodb_buffer_pool_wait_free。
查看innodb buffer pool實時狀態信息:
mysql> show status like ‘Innodb_buffer_pool_%‘;
+-----------------------------------------+---------------+
| Variable_name | Value |
+-----------------------------------------+---------------+
| Innodb_buffer_pool_pages_data | 999020 |
| Innodb_buffer_pool_pages_dirty | 47643 |
| Innodb_buffer_pool_pages_flushed | 474668167 |
| Innodb_buffer_pool_pages_LRU_flushed | 365125 |
| Innodb_buffer_pool_pages_free | 0 |
| Innodb_buffer_pool_pages_made_not_young | 0 |
| Innodb_buffer_pool_pages_made_young | 203410903 |
| Innodb_buffer_pool_pages_misc | 49552 |
| Innodb_buffer_pool_pages_old | 368697 |
| Innodb_buffer_pool_pages_total | 1048572 |
| Innodb_buffer_pool_read_ahead_rnd | 0 |
| Innodb_buffer_pool_read_ahead | 66348855 |
| Innodb_buffer_pool_read_ahead_evicted | 3716819 |
| Innodb_buffer_pool_read_requests | 3215992991498 |
| Innodb_buffer_pool_reads | 65634998 |
| Innodb_buffer_pool_wait_free | 651 |
| Innodb_buffer_pool_write_requests | 21900970785 |
+-----------------------------------------+---------------+
事務看事務的增長頻率,如每秒增長1000。則TPS就是1000。
另外就是看unpurge,undo的情況,避免由於事務長時間未提交導致大量的undo。unpurge。
慢日誌要常常分析。
看TPS有幾種方法:
1、(Handler_commit_d + Handler_rollback_d)/Uptime_d
2、innodb max trx id增長率
幾個wait
Innodb_buffer_pool_wait_free:表示當前buffer pool不夠用了。須要其它buffer釋放。會產生等待事件。
Innodb_log_waits:表示當前redo log不夠用了。
查看MySQL狀態(總體狀態)
- show [full] processlist
- show [global] status
- show engine innodb status\G
- tail -f slow.log
show [full] processlist:MySQL當前線程運行狀態
MySQL鎖監控
- 表級鎖
- Table_locks_immediate
- Table_locks_waited
- 行級鎖
- innodb_row_lock_current_waits 當前等待的行鎖數量(不是行的數量。是鎖的數量)
- innodb_row_lock_time 請求行鎖總耗時(ms)
- innodb_row_lock_time_avg 請求行鎖平均耗時(ms)
- innodb_row_lock_time_max 請求行鎖最舊耗時(ms)
- innodb_row_lock_waits 行鎖發生次數
查看processlist。假設狀態為copying to temp table。代表沒有索引。
還有看processlist的運行時間,長的話要註意。
看SQL的運行代價:
mysql > flush status;
mysql > select ...;
mysql > show status llike ‘handler_read%‘
看handler_read_rnd
看handler_read_rnd
看SQL的瓶頸在哪裏:(用profiling)
mysql > set profiling=1;
mysql > select ...;
mysql > show profiles;
mysql > show profile for query N;
innodb status
show engine innodb status
活躍事務。活躍了多少秒,多少個行鎖,鎖了多少行,產生多少undo。
slow log
percona分支版本號會添加一些額外的信息。
等待事件
innodb_buffer_pool_wait_free
innodb_log_waits等
暫時表/暫時文件
created_tmp_disk_tables
created_tmp_files
打開表/文件數
open_files
open_table_definitions
open_tables
Opened_files
Opened_table_definitions
Opened_tables
並發連接
thread_running
thread_created
thread_cached
業務監控
數據庫正常,但業務不可用,一點意義都沒有。
show global status關鍵參數解讀
- aborted_clients
由於客戶端沒有正確關閉導致客戶端終止而中斷的連接數。 aborted_connects
視圖連接到MySQLserver而失敗的連接數。
aborted_clients記錄的是已經建立正常連接後又被異常斷開的情形。而aborted_connects記錄的是未能正常建立連接的情形。
假設aborted_clients非常高,可能是連接超時時間設置太短了。結果大量連接被自己主動關閉。Binlog_cache_disk_use
使用二進制日誌緩存但超過 binlog_cache_size 值並使用暫時文件來保存事務中的語句的事務數量。原因是binlog cache設置的太小。
- Binlog_cache_use
使用暫時二進制日誌緩存的事務數量。
binlog hit ratio = (Binlog_cache_use)/( Binlog_cache_use + Binlog_cac he_disk_use)*100%
Binlog_stmt_cache_disk_use
The number of nontransaction statements that used the binary log statement cache but that exceeded the value of binlog_stmt_cache_size and used a temporary file to store those statements.
當非事務語句使用二進制日誌緩存,可是超出 binlog_stmt_cache_size 時,使用一個暫時文件來存放這些語句。(innodb的binlog存放在binlog cache中,非事務引擎的binlog存放在binlog_stmt_cache中)
Connections
試圖連接到(無論是否成功)MySQL server的連接數。Created_tmp_disk_tables
server運行語句時在硬盤上自己主動創建的暫時表的數量。是指在排序時。內存不夠 用(tmp_table_size 小於須要排序的結果集),所以須要創建基於磁盤的暫時表進 行排序。
created_tmp_disk_tables/(created_tmp_disk_tables + created_tmp_tables) *100% >10%的話,須要適當提高tmp_table_size的大小。可是不能設置太大。由於它是每一個session都會分配的,可能會導致OOM。Handler_commit
內部提交語句數。
一次 update、delete 後,handler_commit 也是添加 2。 一次 select 後,handler_commit 添加 1。Handler_rollback
內部 ROLLBACK 語句的數量。Handler_read_first
索引中第一條記錄被讀的次數。假設較高。它表明server正運行大量全索引掃 ; 比如,SELECT * order by id,假定 id 列有索引。Handler_read_key
依據索引讀一行的請求數。假設較高,說明查詢和表的索引正確。 比如:select … where id = 1024;
Handler_read_last
查詢讀索引最後一個索引鍵的請求數。當使用 ORDER BY 時。server優先發出使 用第一個索引的請求,之後順序往後掃 索引。當使用 ORDER BY DESC 時,服務 器優先發出使用最後一個索引的請求, 之後向前掃 索引。
比如:select … order by id desc limit 10;Handler_read_next
依照索引順序讀下一行的請求數。假設你用範圍約束或假設運行索引掃 來查詢 索引列,該值添加。
比如:select id from t where id &get;= 1024 order by id limit 5;Handler_read_prev
依照索引順序讀前一行的請求數。該讀方法主要用於優化 ORDER BY … DESC 比如:select id from t where id &get;= 1024 order by id DESC limit 5;Handler_read_rnd
依據固定位置讀一行的請求數。假設你正運行大量查詢並須要對結果進行排序該 值較高。說明可能使用了大量須要 MySQL 掃 整個表的查詢或沒有正確使用索 引。
比如:select * from t limit 1000,1;
或者:select * from t order by non_key_col limit 100,1;Handler_read_rnd_next
在數據文件裏讀下一行的請求數。假設你正進行大量的表掃 ,該值會較高。通 常說明你的表索引不對或寫入的查詢沒有利用索引。
比如:select * from t order by non_key_col limit 100;Innodb_buffer_pool_wait_free
普通情況,通過後臺向 Innodb buffer pool 寫。可是。假設須要讀或創建頁,而且 沒有幹凈的頁可用。則它還須要先等待頁面清空。該計數器對等待實例進行記數。
假設已經適當設置 Innodb buffer pool 大小。該值應小。
Innodb_log_waits
我們必須等待的時間,由於日誌緩沖區太小,我們在繼續前必須先等待對它清空。Innodb_row_lock_current_waits
當前等待的待鎖定的行數。Innodb_row_lock_time
行鎖定花費的總時間,單位毫秒。Innodb_row_lock_time_avg
行鎖定的平均時間,單位毫秒。Innodb_row_lock_time_max
行鎖定的最長時間。單位毫秒。這個值太大的話。能夠考慮調低 innodb_lock_wait_timeout 值Innodb_row_lock_waits
行鎖發生次數。Open_table_definitions
The number of cached .frm files. 被緩存的.frm 文件數量。Opened_table_definitions
The number of .frm files that have been cached. 被緩存過的.FRM 文件的數量。 這個值假設遠大於Open_table_definitions,說明說明table definition cache不夠用。Open_tables
當前打開的表的數量Opened_tables
已經打開的表的數量。假設 Opened_tables 較大。table_open_cache 值可能太小。這個值假設遠大於Open_tables,說明說明table open cache不夠用。
Queries
已經發送給server的查詢的個數。Questions
發送到server的請求次數(包括正常SQL查詢。以及連接、set等所有請求。
QPS = Questions_d / Uptime_d
Select_full_join
沒有使用索引的聯接的數量。假設該值不為 0,你應細致檢查表的索引。
Select_scan
對第一個表進行全然掃 的聯接的數量。- Slow_queries
查詢時間超過 long_query_time 秒的查詢的個數 - Sort_merge_passes
排序算法已經運行的合並的數量。假設這個變量值較大,應考慮添加 sort_buffer_size 系統變量的值。 - threads_connected
當前打開的連接的數量 - threads_created
創建用來處理連接的線程數。假設threads_created較大,你可能要添加threads_cache_size值。
緩存訪問率的計算方法:
threads_creates/Connections - threads_running
激活的(非睡眠狀態)線程數
Threads_connected 假設比 Threads_created 小非常多。或者Threads_cached 和 *Threads_created 相比小非常多。那就須要加大 thread cache size。
innodb status解讀
查看鎖信息
—–5.7版本號
select * from sys.innodb_lock_waits\G
—–5.6版本號
information_schema以下的
innodb_trx
innodb_locks
innodb_lock_waits
SELECT lw.requesting_trx_id AS request_ID,
trx.trx_mysql_thread_id as request_mysql_ID,
trx.trx_query AS request_command,
lw.blocking_trx_id AS blocking_ID,
trx1.trx_mysql_thread_id as blocking_mysql_ID,
trx1.trx_query AS blocking_command,
lo.lock_index AS lock_index
FROM information_schema.innodb_lock_waits lw
INNER JOIN information_schema.innodb_locks lo
ON lw.requesting_trx_id = lo.lock_trx_id
INNER JOIN information_schema.innodb_locks lo1
ON lw.blocking_trx_id = lo1.lock_trx_id
INNER JOIN information_schema.innodb_trx trx
ON lo.lock_trx_id = trx.trx_id
INNER JOIN information_schema.innodb_trx trx1
ON lo1.lock_trx_id = trx1.trx_id;
MySQL監控