1. 程式人生 > >MySQL寫壓力性能監控與調優

MySQL寫壓力性能監控與調優

host 數據 update 海量 ice mage 調用 有意義 一個

寫壓力調優:數據庫的寫、寫壓力性能監控、寫壓力調優參數
一、關於DB的寫

1、數據庫是一個寫頻繁的系統
2、後臺寫、寫緩存
3、commit需要寫入
4、寫緩存失效或者寫滿-->寫壓力陡增-->寫占讀的帶寬
  1、BBU失效
  2、寫入突然增加、cache滿
5、日誌寫入、臟緩沖區寫入

二、寫壓力性能監控   全面剖析寫壓力:多維度的對寫性能進行監控。 1、OS層面的監控:iostat -x
[[email protected] mydata]# iostat -x
Linux 
2.6.32-642.el6.x86_64 (localhost.chinaitsoft.com) 07/05/2017 _x86_64_ (8 CPU) avg-cpu: %user %nice %system %iowait %steal %idle 0.00 0.00 0.03 0.00 0.00 99.97 Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await r_await w_await svctm %util scd0
0.00 0.00 0.00 0.00 0.01 0.00 7.72 0.00 1.25 1.25 0.00 1.25 0.00 sdc 0.02 0.00 0.01 0.00 0.07 0.00 7.93 0.00 0.89 0.89 0.00 0.72 0.00 sda 0.18 0.13 0.13 0.05 5.38 1.43 37.95 0.00 6.63 3.99 13.77 2.23 0.04 sdb
0.03 0.00 0.01 0.00 0.12 0.00 8.72 0.00 1.14 0.80 35.89 0.71 0.00
  1、寫入的吞吐量:wsec/s sec=512字節=0.5K、寫入的響應時間:await   2、我們需要確認我們的系統是寫入還是讀取的系統,如果是寫入為主的系統,寫壓力自然就大,相關狀態值也就大些。   3、監控系統的io狀況,主要查看%util、r/s、w/s,一般繁忙度在70%,每秒寫也在理想值了;但如果系統目前繁忙度低,每秒寫很低,可以增加寫入。 2、DB層面監控,有沒有寫異常:監控各種pending(掛起)
mysql> show global status like %pend%;
+------------------------------+-------+
| Variable_name                | Value |
+------------------------------+-------+
| Innodb_data_pending_fsyncs   | 0     |     #被掛起的fsync
| Innodb_data_pending_reads    | 0     |     #被掛起的物理讀
| Innodb_data_pending_writes   | 0     |     #被掛起的寫
| Innodb_os_log_pending_fsyncs | 0     |     #被掛起的日誌fsync
| Innodb_os_log_pending_writes | 0     |     #被掛起的日誌寫
+------------------------------+-------+
5 rows in set (0.01 sec)
  寫掛起次數值大於0,甭管是什麽寫掛起,出現掛起的話就說明出現寫壓力,所以值最好的是保持為0。監控“掛起”狀態值,出現大於0且持續增加,報警處理。 3、寫入速度監控:日誌寫、臟頁寫   1、日誌寫入速度監控
mysql> show global status like %log%written;
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| Innodb_os_log_written | 5120  |
+-----------------------+-------+
1 row in set (0.01 sec)
  2、臟頁寫入速度監控
mysql> show global status like %a%written;
+----------------------------+---------+
| Variable_name              | Value   |
+----------------------------+---------+
| Innodb_data_written        | 1073152 |     #目前為止寫的總的數據量,單位字節
| Innodb_dblwr_pages_written | 7       |
| Innodb_pages_written       | 58      |     #寫數據頁的數量
+----------------------------+---------+
3 rows in set (0.01 sec)
  3、關註比值Innodb_dblwr_pages_written / Innodb_dblwr_writes,表示一次寫了多少頁
mysql> show global status like %dblwr%;
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Innodb_dblwr_pages_written | 7     |     #已經寫入到doublewrite buffer的頁的數量
| Innodb_dblwr_writes        | 3     |     #doublewrite寫的次數
+----------------------------+-------+
2 rows in set (0.00 sec)
    1、如果該比值是64:1,說明doublewrite每次都是滿寫,寫的壓力很大。     2、如果系統的double_write比較高的話,iostat看到的wrqm/s(每秒合並寫的值)就高,因為double_write高意味著每次寫基本上都是寫2M,這時候就發生更多的合並,但wrqm/s高並不害怕,因為發生合並是好事,看wrqm/s和繁忙度能不能接受。 4、臟頁的量監控
mysql> show global status like %dirty%;
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| Innodb_buffer_pool_pages_dirty | 0     |     #當前buffer pool中臟頁的數量
| Innodb_buffer_pool_bytes_dirty | 0     |     #當前buffer pool中臟頁的總字節數
+--------------------------------+-------+
2 rows in set (0.01 sec)
 
mysql> show global status like i%total%;
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| Innodb_buffer_pool_pages_total | 8192  |     #buffer pool中數據頁總量
+--------------------------------+-------+
1 row in set (0.01 sec)
  關註比值Innodb_buffer_pool_pages_dirty / Innodb_buffer_pool_pages_total,臟頁占比   通過比值看臟頁是否多,比如臟頁10%的話,可以判斷系統可能不是寫為主的系統。 5、寫性能瓶頸
mysql> show global status like %t_free;
+------------------------------+-------+
| Variable_name                | Value |
+------------------------------+-------+
| Innodb_buffer_pool_wait_free | 0     |
+------------------------------+-------+
1 row in set (0.01 sec)
 
mysql> show global status like %g_waits;
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| Innodb_log_waits | 0     |
+------------------+-------+
1 row in set (0.00 sec)
  1、Innodb_buffer_pool_wait_free,如果該值大於0,說明buffer pool中已經沒有可用頁,等待後臺往回刷臟頁,騰出可用數據頁,這樣就很影響業務了,hang住。   2、Innodb_log_waits,如果該值大於0,說明寫壓力很大,出現了日誌等待。 6、系統真實負載:rows增刪改查 、事務提交、事務回滾
mysql> show global status like i%rows%;
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| Innodb_rows_deleted  | 0     |
| Innodb_rows_inserted | 145   |
| Innodb_rows_read     | 233   |
| Innodb_rows_updated  | 5     |
+----------------------+-------+
4 rows in set (0.01 sec)
 
mysql> show global status like %commit%;
+----------------+-------+
| Variable_name  | Value |
+----------------+-------+
| Com_commit     | 0     |
| Com_xa_commit  | 0     |
| Handler_commit | 16    |
+----------------+-------+
3 rows in set (0.01 sec)
 
mysql> show global status like %rollback%;
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Com_rollback               | 0     |
| Com_rollback_to_savepoint  | 0     |
| Com_xa_rollback            | 0     |
| Handler_rollback           | 0     |
| Handler_savepoint_rollback | 0     |
+----------------------------+-------+
5 rows in set (0.01 sec)
  通過監控系統真實負載,如果業務正常,負載上升,寫壓力是那自然是無可厚非的。此時,就要根據業務具體情況,進行相應的調優。 三、寫壓力調優參數   降低寫壓力、加大寫入的力度。   通過調整參數降低寫壓力時,一定要實時關註iostat系統的各項指標。 1、臟頁刷新的頻率
mysql> show variables like i%depth%;
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_lru_scan_depth | 1024  |
+-----------------------+-------+
1 row in set (0.01 sec)
  默認1024,遍歷lru list刷新臟頁,值越大,說明刷臟頁頻率越高。 2、磁盤刷新臟頁的量磁盤io能力
mysql> show variables like %io_c%;
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| innodb_io_capacity     | 200   |
| innodb_io_capacity_max | 2000  |
+------------------------+-------+
2 rows in set (0.00 sec)
  根據磁盤io能力進行調整,值越大,每次刷臟頁的量越大。 3、redolog調優
mysql> show variables like innodb_log%;
+-----------------------------+----------+
| Variable_name               | Value    |
+-----------------------------+----------+
| innodb_log_buffer_size      | 16777216 |
| innodb_log_checksums        | ON       |     #解決數據在io環節的出錯問題,checksum值檢查
| innodb_log_compressed_pages | ON       |
| innodb_log_file_size        | 50331648 |
| innodb_log_files_in_group   | 2        |
| innodb_log_group_home_dir   | ./       |
| innodb_log_write_ahead_size | 8192     |
+-----------------------------+----------+
7 rows in set (0.01 sec)
  logfile大小和組數可能會導致寫抖動:日誌切換頻率需要監控(文件系統層面技巧)。 4、redolog的刷新機制
mysql> show variables like %flush%commit;
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 1     |
+--------------------------------+-------+
1 row in set (0.00 sec)
  默認MySQL的刷盤策略是1,最安全的,但是安全的同時,自然也就會帶來一定的性能壓力。在寫壓力巨大的情況下,根據具體的業務場景,犧牲安全性的將其調為0或2。
關於redolog的刷盤策略:   也就是用戶在commit,事務提交時,處理redolog的方式(0、1、2): 技術分享   0:當提交事務時,並不將事務的redo log寫入logfile中,而是等待master thread每秒的刷新redo log。(數據庫崩潰丟失數據,丟一秒鐘的事務)
  1:執行commit時將redo log同步寫到磁盤logfile中,即伴有fsync的調用(默認是1,保證不丟失事務)
  2:在每個提交,日誌緩沖被寫到文件系統緩存,但不是寫到磁盤的刷新(數據庫宕機而操作系統及服務器並沒有宕機,當恢復時能保證數據不丟失;但是文件系統(OS)崩潰會丟失數據)
5、定義每次日誌刷新的時間
mysql> show variables like innodb_flush_log_at_timeout;
+-----------------------------+-------+
| Variable_name               | Value |
+-----------------------------+-------+
| innodb_flush_log_at_timeout | 1     |
+-----------------------------+-------+
1 row in set (0.01 sec)
  默認是1,也就是每秒log刷盤,配合innodb_flush_log_at_trx_commit來設置,為了充分保證數據的一致性,一般innodb_flush_log_at_trx_commit=1,這樣的話,innodb_flush_log_at_timeout的設置也就沒有意義了。因此,該參數的設置只針對innodb_flush_log_at_trx_commit為0/2起作用。 6、內存臟頁占比控制
mysql> show variables like %dirty%pct%;
+--------------------------------+-----------+
| Variable_name                  | Value     |
+--------------------------------+-----------+
| innodb_max_dirty_pages_pct     | 75.000000 |     #臟頁在buffer pool中的最大占比
| innodb_max_dirty_pages_pct_lwm | 0.000000  |
+--------------------------------+-----------+
2 rows in set (0.01 sec)

  在內存buffer pool空間允許的範圍下,可以調大臟頁允許在內存空間的占比,可解燃眉之急,降低寫壓力。

7、關閉doublewrite降低寫壓力
mysql> show variables like %doub%;
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| innodb_doublewrite | ON    |
+--------------------+-------+
1 row in set (0.01 sec)
  兩次寫特性,默認開啟,靜態參數。關閉doublewrite適合的場景:   1、海量DML   2、不懼怕數據損壞和丟失   3、系統寫負載成為主要負載,關閉doublewrite,降低寫壓力 註意:   關於參數調整的生效範圍,如何調整(靜態參數、動態參數),都是要依據官方文檔,依照文檔進行調參。

MySQL寫壓力性能監控與調優