通過show status 優化數據庫性能

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行鎖是基於索引來鎖定的),造成間隙鎖過大。也可能是系統本身處理能力有限,則需要從其他方面來考慮解決。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章