MySQL寫壓力性能監控與調優

1、關於DB的寫

一、數據庫是一個寫頻繁的系統
二、後臺寫、寫緩存
三、commit須要寫入
四、寫緩存失效或者寫滿-->寫壓力陡增-->寫佔讀的帶寬
  一、BBU失效
  二、寫入忽然增長、cache滿
五、日誌寫入、髒緩衝區寫入mysql

 
2、寫壓力性能監控
  全面剖析寫壓力:多維度的對寫性能進行監控。
一、OS層面的監控:iostat -x
[root@localhost 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
  一、寫入的吞吐量:wsec/s  sec=512字節=0.5K、 寫入的響應時間:await
  二、咱們須要確認咱們的系統是寫入仍是讀取的系統,若是是寫入爲主的系統,寫壓力天然就大,相關狀態值也就大些。
  三、監控系統的io情況,主要查看%util、r/s、w/s,通常繁忙度在70%,每秒寫也在理想值了;但若是系統目前繁忙度低,每秒寫很低,能夠增長寫入。
二、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且持續增長,報警處理。
三、寫入速度監控:日誌寫、髒頁寫
  一、日誌寫入速度監控
mysql> show global status like '%log%written';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| Innodb_os_log_written | 5120  |
+-----------------------+-------+
1 row in set (0.01 sec)
  二、髒頁寫入速度監控
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)
  三、關注比值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)
    一、若是該比值是64:1,說明doublewrite每次都是滿寫,寫的壓力很大。
    二、若是系統的double_write比較高的話,iostat看到的wrqm/s(每秒合併寫的值)就高,由於double_write高意味着每次寫基本上都是寫2M,這時候就發生更多的合併,但wrqm/s高並不懼怕,由於發生合併是好事,看wrqm/s和繁忙度能不能接受。 
四、髒頁的量監控
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%的話,能夠判斷系統可能不是寫爲主的系統。
五、寫性能瓶頸
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)
  一、Innodb_buffer_pool_wait_free,若是該值大於0,說明buffer pool中已經沒有可用頁,等待後臺往回刷髒頁,騰出可用數據頁,這樣就很影響業務了,hang住。
  二、Innodb_log_waits,若是該值大於0,說明寫壓力很大,出現了日誌等待。
六、系統真實負載: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)
  經過監控系統真實負載,若是業務正常,負載上升,寫壓力是那天然是無可厚非的。此時,就要根據業務具體狀況,進行相應的調優。 
 
3、寫壓力調優參數
  下降寫壓力、加大寫入的力度。
  經過調整參數下降寫壓力時,必定要實時關注iostat系統的各項指標。
一、髒頁刷新的頻率
mysql> show variables like 'i%depth%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_lru_scan_depth | 1024  |
+-----------------------+-------+
1 row in set (0.01 sec)
  默認1024,遍歷lru list刷新髒頁,值越大,說明刷髒頁頻率越高。
二、磁盤刷新髒頁的量磁盤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能力進行調整,值越大,每次刷髒頁的量越大。
三、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大小和組數可能會致使寫抖動:日誌切換頻率須要監控(文件系統層面技巧)。
四、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、一、2):
  0:當提交事務時,並不將事務的redo log寫入logfile中,而是等待master thread每秒的刷新redo log。(數據庫崩潰丟失數據,丟一秒鐘的事務)
  1:執行commit時將redo log同步寫到磁盤logfile中,即伴有fsync的調用(默認是1,保證不丟失事務)
  2:在每一個提交,日誌緩衝被寫到文件系統緩存,但不是寫到磁盤的刷新(數據庫宕機而操做系統及服務器並無宕機,當恢復時能保證數據不丟失;可是文件系統(OS)崩潰會丟失數據)
五、定義每第二天志刷新的時間
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起做用。
六、內存髒頁佔比控制
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空間容許的範圍下,能夠調大髒頁容許在內存空間的佔比,可解燃眉之急,下降寫壓力。ios

七、關閉doublewrite下降寫壓力
mysql> show variables like '%doub%';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| innodb_doublewrite | ON    |
+--------------------+-------+
1 row in set (0.01 sec)
  兩次寫特性,默認開啓,靜態參數。關閉doublewrite適合的場景:
  一、海量DML
  二、不害怕數據損壞和丟失
  三、系統寫負載成爲主要負載,關閉doublewrite,下降寫壓力
注意:
  關於參數調整的生效範圍,如何調整(靜態參數、動態參數),都是要依據官方文檔,依照文檔進行調參。
相關文章
相關標籤/搜索