1. 程式人生 > >MySQL checkpoint深入分析

MySQL checkpoint深入分析

 

 

1、日常關注點的問題

2、日誌點分析

3、checkpoint:髒頁刷盤的檢查點

4、模糊檢查點發生條件

  1、master thread checkpoint

  2、flush_lru_list checkpoint

  3、async/sync flush checkpoint

  4、dirty page too much checkpoint

一、日常關注的問題

 

1、我們的日誌生成速度?

  1、每天生成多少日誌、產生多少redo log

mysql> show global status like 'Innodb_os_log_written';
+-----------------------+--------+
| Variable_name         | Value  |
+-----------------------+--------+
| Innodb_os_log_written | 107008 |
+-----------------------+--------+
1 row in set (0.01 sec)

  2、如果redolog量大,需要修改如下引數,增加logfile的大小和組數

mysql> show variables like 'i%log_file%';
+---------------------------+----------+
| Variable_name             | Value    |
+---------------------------+----------+
| innodb_log_file_size      | 50331648 |
| innodb_log_files_in_group | 2        |
+---------------------------+----------+
2 rows in set (0.00 sec)

2、日誌寫入速度?

  Log buffer有沒有滿、滿的話為什麼滿

mysql> show variables like 'i%log_buffer%';
+------------------------+----------+
| Variable_name          | Value    |
+------------------------+----------+
| innodb_log_buffer_size | 16777216 |
+------------------------+----------+
1 row in set (0.01 sec)

mysql> show global status like '%log_pending%';
+------------------------------+-------+
| Variable_name                | Value |
+------------------------------+-------+
| Innodb_os_log_pending_fsyncs | 0     |
| Innodb_os_log_pending_writes | 0     |
+------------------------------+-------+
2 rows in set (0.01 sec)

3、髒頁的寫入速度?

  1、Log buffer滿了會hang住

  2、Logfile滿了不能被覆蓋也會hang住

  3、如果髒頁寫入速度慢的話,logfile滿了也不能被覆蓋,系統容易hang住,log buffer如果滿了的話也容易hang住。

4、資料庫啟動時間是多少?

  啟動時,預設是要先恢復髒頁。當然,能通過引數innodb_force_recovery啟動控制。

  如果innodb_buffer_pool很大,32G,極端情況可能有32G的髒頁,這個時候如果崩了,恢復的話需要恢復這32G的髒頁,時間非常長。

 

二、日誌點分析

  通過show engine innodb status\G解釋一下LOG相關的四行引數的值:

Log sequence number 143942609---LSN:日誌序列號(1)  

  //位元組,日誌生成的最新位置,最新位置出現在log buffer中

Log flushed up to   143942609---(2)  

  //位元組,日誌已經寫入到log file的位置,1-2=log buffer日誌量,最好是<=1M

Pages flushed up to 143942609---(3)  

  //位元組,髒頁的數量(日誌位元組數來衡量),2-3=髒頁的數量(日誌位元組為單位)

Last checkpoint at  143942600---(4)  

  //位元組,共享表空間上的日誌記錄點,最後一次檢查點,及崩潰恢復時指定的起點,3-4就是崩潰恢復多跑的日誌,值越大說明需要提升checkpoint的跟進速度

 

三、checkpoint

  檢查點,表示髒頁寫入到磁碟的時候,所以檢查點也就意味著髒資料的寫入。

1、checkpoint的目的

  1、縮短資料庫的恢復時間

  2、buffer pool空間不夠用時,將髒頁重新整理到磁碟

  3、redolog不可用時,重新整理髒頁

2、檢查點分類

  1、sharp checkpoint:完全檢查點,資料庫正常關閉時,會觸發把所有的髒頁都寫入到磁碟上(這時候logfile的日誌就沒用了,髒頁已經寫到磁碟上了)。

    1、完全檢查點,發生在資料庫正常關閉的時候。

    2、在資料庫在執行時不會使用sharp checkpoint,在引擎內部使用fuzzy checkpoint,即只重新整理一部分髒頁,而不是重新整理所有的髒頁回磁碟。

  2、fuzzy checkpoint:模糊檢查點,部分頁寫入磁碟。

    1、發生在資料庫正常執行期間。

    2、模糊檢查點,不是sharp的就是模糊檢查點(4種):master thread checkpoint、flush_lru_list checkpoint、async/sync flush checkpoint、dirty page too much checkpoint。

 

四、fuzzy checkpoint發生的4個條件

  模糊檢查點的發生,也就是髒頁寫入磁碟的情況。

1、master thread checkpoint

  差不多以每秒或每十秒的速度從緩衝池的髒頁列表中重新整理一定比例的頁回磁碟,這個過程是非同步的,不會阻塞使用者查詢。

  1、週期性,讀取flush list,找到髒頁,寫入磁碟

  2、寫入的量比較小

  3、非同步,不影響業務

mysql> show variables like '%io_cap%';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| innodb_io_capacity     | 200   |
| innodb_io_capacity_max | 2000  |
+------------------------+-------+
2 rows in set (0.01 sec)

  4、通過capacity能力告知進行刷盤控制

    通過innodb的io能力告知控制對flush list刷髒頁數量,io_capacity越高,每次刷盤寫入髒頁數越多;

    如果髒頁數量過多,刷盤速度很慢,在io能力允許的情況下,調高innodb_io_capacity值,讓多刷髒頁。

2、flush_lru_list checkpoint

  MySQL會保證,保證裡面有多少可用的空閒頁,在innodb 1.1.x版本之前,需要檢查在使用者查詢執行緒中是否有足夠的可用空間(差不多100個空閒頁),顯然這會阻塞使用者執行緒,如果沒有100個可用空閒頁,那麼innodbhi將lru列表尾端的頁移除,如果這些頁中有髒頁,那麼需要進行checkpoint。Innodb 1.2(5.6)之後把他單獨放到一個執行緒page cleaner中進行,使用者可以通過引數innodb_lru_scan_depth控制lru列表中可用頁的數量,預設是1024。

  讀取lru list,找到髒頁,寫入磁碟。

mysql> show variables like '%lru%depth';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_lru_scan_depth | 1024  |
+-----------------------+-------+
1 row in set (0.01 sec)

  此情況下觸發,預設掃描1024個lru冷端資料頁,將髒頁寫入磁碟(有10個就刷10,有100個就刷100個……)   

3、async/sync flush checkpoint

  log file快滿了,會批量的觸發資料頁回寫,這個事件觸發的時候又分為非同步和同步,不可被覆蓋的redolog佔log file的比值:75%--->非同步、90%--->同步。

  當這兩個事件中的任何一個發生的時候,都會記錄到errlog中,一旦errlog出現這種日誌提示,一定需要加大logfile。

  Async/Sync Flush Checkpoint是為了保證重做日誌的迴圈使用的可用性。在InnoDB 1.2.x版本之前,Async Flush Checkpoint會阻塞發現問題的使用者查詢執行緒,而Sync Flush Checkpoint會阻塞所有的使用者查詢執行緒,並且等待髒頁重新整理完成。從InnoDB 1.2.x版本開始——也就是MySQL 5.6版本,這部分的重新整理操作同樣放入到了單獨的Page Cleaner Thread中,故不會阻塞使用者查詢執行緒。

4、dirty page too much checkpoint

  很明顯,髒頁太多檢查點,為了保證buffer pool的空間可用性的一個檢查點。

  1、髒頁監控,關注點

mysql> show global status like 'Innodb_buffer_pool_pages%t%';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| Innodb_buffer_pool_pages_data  | 2964  |
| Innodb_buffer_pool_pages_dirty | 0     |
| Innodb_buffer_pool_pages_total | 8191  |
+--------------------------------+-------+
3 rows in set (0.00 sec)

mysql> show global status like '%wait_free';
+------------------------------+-------+
| Variable_name                | Value |
+------------------------------+-------+
| Innodb_buffer_pool_wait_free | 0     |
+------------------------------+-------+
1 row in set (0.00 sec)

    1、Innodb_buffer_pool_pages_dirty/Innodb_buffer_pool_pages_total:表示髒頁在buffer 的佔比

    2、Innodb_buffer_pool_wait_free:如果>0,說明出現效能負載,buffer pool中沒有乾淨可用塊

  2、髒頁控制引數

mysql> show variables like '%dirty%pct%';
+--------------------------------+-----------+
| Variable_name                  | Value     |
+--------------------------------+-----------+
| innodb_max_dirty_pages_pct     | 75.000000 |
| innodb_max_dirty_pages_pct_lwm | 0.000000  |
+--------------------------------+-----------+
2 rows in set (0.01 sec)

    1、預設是髒頁佔比75%的時候,就會觸發刷盤,將髒頁寫入磁碟,騰出記憶體空間。建議不調,調太低的話,io壓力就會很大,但是崩潰恢復就很快;

    2、lwm:low water mark低水位線,刷盤到該低水位線就不寫髒頁了,0也就是不限制。

注意:上面在調整的時候,要關注系統的寫效能iostat -x。

@author:http://www.cnblogs.com/geaozhang/

1、日常關注點的問題

2、日誌點分析

3、checkpoint:髒頁刷盤的檢查點

4、模糊檢查點發生條件

  1、master thread checkpoint

  2、flush_lru_list checkpoint

  3、async/sync flush checkpoint

  4、dirty page too much checkpoint

一、日常關注的問題

 

1、我們的日誌生成速度?

  1、每天生成多少日誌、產生多少redo log

mysql> show global status like 'Innodb_os_log_written';
+-----------------------+--------+
| Variable_name         | Value  |
+-----------------------+--------+
| Innodb_os_log_written | 107008 |
+-----------------------+--------+
1 row in set (0.01 sec)

  2、如果redolog量大,需要修改如下引數,增加logfile的大小和組數

mysql> show variables like 'i%log_file%';
+---------------------------+----------+
| Variable_name             | Value    |
+---------------------------+----------+
| innodb_log_file_size      | 50331648 |
| innodb_log_files_in_group | 2        |
+---------------------------+----------+
2 rows in set (0.00 sec)

2、日誌寫入速度?

  Log buffer有沒有滿、滿的話為什麼滿

mysql> show variables like 'i%log_buffer%';
+------------------------+----------+
| Variable_name          | Value    |
+------------------------+----------+
| innodb_log_buffer_size | 16777216 |
+------------------------+----------+
1 row in set (0.01 sec)

mysql> show global status like '%log_pending%';
+------------------------------+-------+
| Variable_name                | Value |
+------------------------------+-------+
| Innodb_os_log_pending_fsyncs | 0     |
| Innodb_os_log_pending_writes | 0     |
+------------------------------+-------+
2 rows in set (0.01 sec)

3、髒頁的寫入速度?

  1、Log buffer滿了會hang住

  2、Logfile滿了不能被覆蓋也會hang住

  3、如果髒頁寫入速度慢的話,logfile滿了也不能被覆蓋,系統容易hang住,log buffer如果滿了的話也容易hang住。

4、資料庫啟動時間是多少?

  啟動時,預設是要先恢復髒頁。當然,能通過引數innodb_force_recovery啟動控制。

  如果innodb_buffer_pool很大,32G,極端情況可能有32G的髒頁,這個時候如果崩了,恢復的話需要恢復這32G的髒頁,時間非常長。

 

二、日誌點分析

  通過show engine innodb status\G解釋一下LOG相關的四行引數的值:

Log sequence number 143942609---LSN:日誌序列號(1)  

  //位元組,日誌生成的最新位置,最新位置出現在log buffer中

Log flushed up to   143942609---(2)  

  //位元組,日誌已經寫入到log file的位置,1-2=log buffer日誌量,最好是<=1M

Pages flushed up to 143942609---(3)  

  //位元組,髒頁的數量(日誌位元組數來衡量),2-3=髒頁的數量(日誌位元組為單位)

Last checkpoint at  143942600---(4)  

  //位元組,共享表空間上的日誌記錄點,最後一次檢查點,及崩潰恢復時指定的起點,3-4就是崩潰恢復多跑的日誌,值越大說明需要提升checkpoint的跟進速度

 

三、checkpoint

  檢查點,表示髒頁寫入到磁碟的時候,所以檢查點也就意味著髒資料的寫入。

1、checkpoint的目的

  1、縮短資料庫的恢復時間

  2、buffer pool空間不夠用時,將髒頁重新整理到磁碟

  3、redolog不可用時,重新整理髒頁

2、檢查點分類

  1、sharp checkpoint:完全檢查點,資料庫正常關閉時,會觸發把所有的髒頁都寫入到磁碟上(這時候logfile的日誌就沒用了,髒頁已經寫到磁碟上了)。

    1、完全檢查點,發生在資料庫正常關閉的時候。

    2、在資料庫在執行時不會使用sharp checkpoint,在引擎內部使用fuzzy checkpoint,即只重新整理一部分髒頁,而不是重新整理所有的髒頁回磁碟。

  2、fuzzy checkpoint:模糊檢查點,部分頁寫入磁碟。

    1、發生在資料庫正常執行期間。

    2、模糊檢查點,不是sharp的就是模糊檢查點(4種):master thread checkpoint、flush_lru_list checkpoint、async/sync flush checkpoint、dirty page too much checkpoint。

 

四、fuzzy checkpoint發生的4個條件

  模糊檢查點的發生,也就是髒頁寫入磁碟的情況。

1、master thread checkpoint

  差不多以每秒或每十秒的速度從緩衝池的髒頁列表中重新整理一定比例的頁回磁碟,這個過程是非同步的,不會阻塞使用者查詢。

  1、週期性,讀取flush list,找到髒頁,寫入磁碟

  2、寫入的量比較小

  3、非同步,不影響業務

mysql> show variables like '%io_cap%';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| innodb_io_capacity     | 200   |
| innodb_io_capacity_max | 2000  |
+------------------------+-------+
2 rows in set (0.01 sec)

  4、通過capacity能力告知進行刷盤控制

    通過innodb的io能力告知控制對flush list刷髒頁數量,io_capacity越高,每次刷盤寫入髒頁數越多;

    如果髒頁數量過多,刷盤速度很慢,在io能力允許的情況下,調高innodb_io_capacity值,讓多刷髒頁。

2、flush_lru_list checkpoint

  MySQL會保證,保證裡面有多少可用的空閒頁,在innodb 1.1.x版本之前,需要檢查在使用者查詢執行緒中是否有足夠的可用空間(差不多100個空閒頁),顯然這會阻塞使用者執行緒,如果沒有100個可用空閒頁,那麼innodbhi將lru列表尾端的頁移除,如果這些頁中有髒頁,那麼需要進行checkpoint。Innodb 1.2(5.6)之後把他單獨放到一個執行緒page cleaner中進行,使用者可以通過引數innodb_lru_scan_depth控制lru列表中可用頁的數量,預設是1024。

  讀取lru list,找到髒頁,寫入磁碟。

mysql> show variables like '%lru%depth';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_lru_scan_depth | 1024  |
+-----------------------+-------+
1 row in set (0.01 sec)

  此情況下觸發,預設掃描1024個lru冷端資料頁,將髒頁寫入磁碟(有10個就刷10,有100個就刷100個……)   

3、async/sync flush checkpoint

  log file快滿了,會批量的觸發資料頁回寫,這個事件觸發的時候又分為非同步和同步,不可被覆蓋的redolog佔log file的比值:75%--->非同步、90%--->同步。

  當這兩個事件中的任何一個發生的時候,都會記錄到errlog中,一旦errlog出現這種日誌提示,一定需要加大logfile。

  Async/Sync Flush Checkpoint是為了保證重做日誌的迴圈使用的可用性。在InnoDB 1.2.x版本之前,Async Flush Checkpoint會阻塞發現問題的使用者查詢執行緒,而Sync Flush Checkpoint會阻塞所有的使用者查詢執行緒,並且等待髒頁重新整理完成。從InnoDB 1.2.x版本開始——也就是MySQL 5.6版本,這部分的重新整理操作同樣放入到了單獨的Page Cleaner Thread中,故不會阻塞使用者查詢執行緒。

4、dirty page too much checkpoint

  很明顯,髒頁太多檢查點,為了保證buffer pool的空間可用性的一個檢查點。

  1、髒頁監控,關注點

mysql> show global status like 'Innodb_buffer_pool_pages%t%';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| Innodb_buffer_pool_pages_data  | 2964  |
| Innodb_buffer_pool_pages_dirty | 0     |
| Innodb_buffer_pool_pages_total | 8191  |
+--------------------------------+-------+
3 rows in set (0.00 sec)

mysql> show global status like '%wait_free';
+------------------------------+-------+
| Variable_name                | Value |
+------------------------------+-------+
| Innodb_buffer_pool_wait_free | 0     |
+------------------------------+-------+
1 row in set (0.00 sec)

    1、Innodb_buffer_pool_pages_dirty/Innodb_buffer_pool_pages_total:表示髒頁在buffer 的佔比

    2、Innodb_buffer_pool_wait_free:如果>0,說明出現效能負載,buffer pool中沒有乾淨可用塊

  2、髒頁控制引數

mysql> show variables like '%dirty%pct%';
+--------------------------------+-----------+
| Variable_name                  | Value     |
+--------------------------------+-----------+
| innodb_max_dirty_pages_pct     | 75.000000 |
| innodb_max_dirty_pages_pct_lwm | 0.000000  |
+--------------------------------+-----------+
2 rows in set (0.01 sec)

    1、預設是髒頁佔比75%的時候,就會觸發刷盤,將髒頁寫入磁碟,騰出記憶體空間。建議不調,調太低的話,io壓力就會很大,但是崩潰恢復就很快;

    2、lwm:low water mark低水位線,刷盤到該低水位線就不寫髒頁了,0也就是不限制。

注意:上面在調整的時候,要關注系統的寫效能iostat -x。