1. 程式人生 > >MySQL監控

MySQL監控

設置 ase mysql鎖 delet engine exc views mys ext

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監控