1. 程式人生 > >通過show status 優化資料庫效能

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