通過show status 優化資料庫效能
阿新 • • 發佈:2019-02-10
mysql資料庫的效能狀態監控點非常多,其中很多量都是不能忽視的必須監控的量,且90%以上的內容 可以在連線上mysql後執行show status 或是 show veriables的輸出值 獲得,需要注意的是以上的命令獲得的狀態值實際上是累計值,所以如果 要計算時段內的變化 量還需要稍加處理,下面看下幾項需要重點關注的效能狀態:
1. key buffer 命中率
key buffer 命中率代表了myisam型別表的索引cache命中率,命中率的大小直接影響myisam型別表的讀寫效能。key buffer 命中率實際上包括讀命中率和寫命中率兩種,mysql中並沒有直接給出這兩個命中率的值,但是可以通過如下方式計算:
key_buffer_read_hits=(1-key_reads/key_read_requests) * 100%
key_buffer_write_hits=(1-key_writes/key-write-requests)*100%
獲取所需要狀態的變數值:
show status like 'key%'
mysql> show status like 'key%';
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| Key_blocks_not_flushed | 0 |
| Key_blocks_unused | 13396 |
| Key_blocks_used | 19 |
| Key_read_requests | 71 |
| Key_reads | 19 |
| Key_write_requests | 1 |
| Key_writes | 1 |
+------------------------+-------+
7 rows in set (0.00 sec)
命中率過低,說明myisam型別表的讀寫存在問題。
2. innodb buffer 命中率
這裡innodb buffer 所指的是innodb_buffer_pool,也就是用來快取innodb型別表和索引的內在空間。類似key buffer,同樣可以根據mysql提供的相應的狀態資訊計算其命中率:
innodb_buffer_read_hits=(1-innodb_buffer_pool_reads/innodb_buffer_pool_read_requests) * 100%;
獲取所需狀態變數值:
mysql> show status like 'innodb_buffer_pool_read%';
+---------------------------------------+----------+
| Variable_name | Value |
+---------------------------------------+----------+
| Innodb_buffer_pool_read_ahead_rnd | 0 |
| Innodb_buffer_pool_read_ahead | 0 |
| Innodb_buffer_pool_read_ahead_evicted | 0 |
| Innodb_buffer_pool_read_requests | 27269024 |
| Innodb_buffer_pool_reads | 827 |
+---------------------------------------+----------+
命中率過低,說明innodb型別表的讀寫存在問題。
3. query cache命中率
query cache 是mysql的查詢cache,在my.cnf配置檔案若開啟,則可以對查詢過的語句結果進行cache。對於一些使用者數不高或一次性統計平臺建議關閉查詢快取。若開啟query cache,則對query cache 命中率進行監控也是需要的,它可以告訴我們是資料庫是否在正確使用query cache。query cache命中率計算如下:
query_cache_hits =(Qcache_hits/(Qcache_hits+Qcache_inserts))* 100%;
獲取變數值:
mysql> show status like 'Qcache%';
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| Qcache_free_blocks | 0 |
| Qcache_free_memory | 0 |
| Qcache_hits | 0 |
| Qcache_inserts | 0 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 0 |
| Qcache_queries_in_cache | 0 |
| Qcache_total_blocks | 0 |
+-------------------------+-------+
8 rows in set (0.00 sec)
4. table_cache 命中率
table_cache指定表調整快取的大小,當mysql訪問某個表時,若表快取空間還有空間,則將該表就被開啟並將資料放入其中,下次訪問此表時可以更快的訪問表的內容。通過查峰值時間的狀態值open_tables 和 opened_tables可以決定是否需要增加table_cache值。需要注意的是table_cache設定很太高,可能會造成檔案描述符不足,從而造成效能不穩定或是連線失敗。
table_cache的當前狀態量可以幫助我們判斷系統引數table_open_cache的設定是否合理。如果狀態量open_tables與opened_tables之間的比率過低,則代表table cache設定過小,網上有人認為這值的比率設定在80%最好。
獲取變數:
mysql> show status like 'open%';
+--------------------------+---------+
| Variable_name | Value |
+--------------------------+---------+
| Open_files | 6 |
| Open_streams | 0 |
| Open_table_definitions | 87 |
| Open_tables | 26 |
| Opened_files | 1554504 |
| Opened_table_definitions | 0 |
| Opened_tables | 0 |
+--------------------------+---------+
5. thread cache命中率
在mysql中,為了儘可能提高客戶端連線的過程,實現 了一個thread cache池,將空閒的連線執行緒存放在其中,而不是請求完成後銷燬,當有新的連線請求的時候,mysql首先檢查thread cache是否儲存空閒的連線執行緒,如果存在則取出來直接使用,如果沒有空閒連線執行緒,才建立新的執行緒。
thread cache命中率能直接反應出系統引數thread_cache_size設定是否合理。一個合理的read_cache_size引數能夠節約大量建立新連線時所需要消夏的資源。
thread cache命中率計算方式如下:
thread_cache_hits = (1- threads_created/connections) * 100 %;
獲取所需要狀態變數值:
mysql> show status like 'thread%';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Threads_cached | 0 |
| Threads_connected | 1 |
| Threads_created | 23581 |
| Threads_running | 1 |
+-------------------+-------+
正常來說,thread cache命中率在90%以上才算合理。
6. tmp table相關狀況分析
tmp table 主要用於監控mysql使用臨時表的量是否過多,是否有臨時表過大而不得不從記憶體中換出到磁碟檔案中,臨時表使用狀態 資訊獲取如下:
mysql> show status like 'created_tmp%';
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| Created_tmp_disk_tables | 0 |
| Created_tmp_files | 65 |
| Created_tmp_tables | 0 |
+-------------------------+-------+
Created_tmp_disk_tables為臨時表過大無法在記憶體中完成,而不得不使用磁碟的次數。若create_tmp_tables非常大,則可甬系統排序操作過多,或者可能是連線方式不是很優化。而如果是create_tmp_dis_table/create_tmp_tables比率過高,如超過10%,則需要考慮tmp_table_size引數是否需要調整大些。建議tmp_table_size與max_heap_table_size需要設定成一樣大。
7. binlog cache
若開啟binlog日誌功能,則需要考慮binlog cache問題。binlog不是一有資料就寫到binlog中,而是先寫入到binlog cache中,再寫入到binlog中。
Binlog_cache_disk_use為binlog使用硬碟使用量, Binlog_cache_use 為binlog已使用的量。若 Binlog_cache_disk_use大於0,則說明binlog_cache不夠用。
mysql> show status like 'binlog_cache%';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Binlog_cache_disk_use | 58 |
| Binlog_cache_use | 39785 |
+-----------------------+-------+
8. innodb_log_waits
innodb_log_waits狀態變數直接反應innodb log buffer 空間不足造成等待的次數。innodb_log_waits直接反應系統的寫入效能,當值 達到每秒1次時,就需要增加innodb_log_buffer_size的值,適當的增加不會造成記憶體不足的問題。
9. 複製延時量
複製延時量:複製延時量將直接影響了Slave資料庫處於不一致狀態的時間長短。如果我們是通過Slave來提供讀服務,就不得不重視這個延時量。我們可以通過在Slave節點上執行“SHOWSLAVESTATUS”命令,取Seconds_Behind_Master項的值來了解Slave當前的延時量(單位:秒)。當然,該值的準確性依賴於複製是否處於正常狀態。每個環境下的Slave所允許的延時長短與具體環境有關,所以複製延時多長時間是合理的,只能由讀者朋友根據各自實際的應用環境來判斷。
mysql> show slave status\G
Seconds_Behind_Master: NULL
10. 鎖狀態
mysql的鎖有表鎖和行鎖,myisam最小鎖為表鎖,innodb最小鎖為行鎖,可以通過以下命令獲取鎖定次數、鎖定造成其他執行緒等待次數,以及鎖定等待時間資訊。
mysql> show status like '%lock%';
+------------------------------------------+---------+
| Variable_name | Value |
+------------------------------------------+---------+
| Com_lock_tables | 0 |
| Com_unlock_tables | 0 |
| 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 |
| Key_blocks_not_flushed | 0 |
| Key_blocks_unused | 13396 |
| Key_blocks_used | 19 |
| Performance_schema_locker_lost | 0 |
| Performance_schema_rwlock_classes_lost | 0 |
| Performance_schema_rwlock_instances_lost | 0 |
| Qcache_free_blocks | 0 |
| Qcache_total_blocks | 0 |
| Table_locks_immediate | 1570736 |
| Table_locks_waited | 7294 |
+------------------------------------------+---------+
如當Table_locks_waited與Table_locks_immediate的比值較大,則說明我們的表鎖造成的阻塞比較嚴重,可能需要調整Query語句,或者更改儲存引擎,亦或者需要調整業務邏輯。當然,具體改善方式必須根據實際場景來判斷。而Innodb_row_lock_waits較大,則說明Innodb的行鎖也比較嚴重,且影響了其他執行緒的正常處理。同樣需要查找出原因並解決。造成Innodb行鎖嚴重的原因可能是Query語句所利用的索引不夠合理(Innodb行鎖是基於索引來鎖定的),造成間隙鎖過大。也可能是系統本身處理能力有限,則需要從其他方面來考慮解決。