MySql學習(專項篇)內存數據落盤

整體思路分析

在這裏插入圖片描述

InnoDB內存緩衝池中的數據page要完成持久化的話,是通過兩個流程來完成的,一個是髒頁落
盤;一個是預寫redo log日誌。

保證數據的持久性

當緩衝池中的頁的版本比磁盤要新時,數據庫需要將新版本的頁從緩衝池刷新到磁盤。但是如果
每次一個頁發送變化,就進行刷新,那麼性能開發是非常大的,於是InnoDB採用了Write Ahead
Log(WAL)策略和Force Log at Commit機制實現事務級別下數據的持久性。

WAL要求數據的變更寫入到磁盤前,首先必須將內存中的日誌寫入到磁盤;
Force-log-at-commit要求當一個事務提交時,所有產生的日誌都必須刷新到磁盤上,如果日誌刷
新成功後,緩衝池中的數據刷新到磁盤前數據庫發生了宕機,那麼重啓時,數據庫可以從日誌中 恢復數據。
爲了確保每次日誌都寫入到重做日誌文件,在每次將重做日誌緩衝寫入重做日誌後,必須調用一
次fsync操作,將緩衝文件從文件系統緩存中真正寫入磁盤。 可以通過 innodb_flush_log_at_trx_commit
來控制重做日誌刷新到磁盤的策略。

髒頁落盤

在數據庫中進行讀取操作,將從磁盤中讀到的頁放在緩衝池中,下次再讀相同的頁時,首先判斷
該頁是否在緩衝池中。若在緩衝池中,稱該頁在緩衝池中被命中,直接讀取該頁。否則,讀取磁 盤上的頁。

對於數據庫中頁的修改操作,則首先修改在緩衝池中的頁,然後再以一定的頻率刷新到磁盤上。
頁從緩衝池刷新回磁盤的操作並不是在每次頁發生更新時觸發,而是通過一種稱爲CheckPoint的 機制刷新回磁盤。

CheckPoint檢查點機制

CheckPoint是爲了解決下面幾個問題:

  1. 縮短數據庫的恢復時間;
  2. 緩衝池不夠用時,將髒頁刷新到磁盤;
  3. 重做日誌不可用時,刷新髒頁

當數據庫發生宕機時,數據庫不需要重做所有的日誌,因爲Checkpoint之前的頁都已經刷新回磁
盤。數據庫只需對Checkpoint後的重做日誌進行恢復,這樣就大大縮短了恢復的時間。

當緩衝池不夠用時,根據LRU算法(最少最近使用原則)會溢出最近最少使用的頁,若此頁爲髒頁,那麼需要強制執行
Checkpoint,將髒頁也就是頁的新版本刷回磁盤。

當重做日誌出現不可用時,因爲當前事務數據庫系統對重做日誌的設計都是循環使用的,並不是讓
其無限增大的。重做日誌可以被重用的部分是指這些重做日誌已經不再需要,當數據庫發生宕機
時,數據庫恢復操作不需要這部分的重做日誌,因此這部分就可以被覆蓋重用。如果重做日誌還需
要使用,那麼必須強制Checkpoint,將緩衝池中的頁至少刷新到當前重做日誌的位置。

CheckPoint分類

在InnoDB存儲引擎內部,有兩種Checkpoint,分別爲:Sharp Checkpoint、Fuzzy Checkpoint

  1. sharp checkpoint:在關閉數據庫的時候,將buffer pool中的髒頁全部刷新到磁盤中
  2. fuzzy checkpoint:數據庫正常運行時,在不同的時機,將部分髒頁寫入磁盤。僅刷新部分髒頁
    到磁盤,也是爲了避免一次刷新全部的髒頁造成的性能問題。
fuzzy checkpoint

Fuzzy Checkpoint分爲以下幾種:

  1. Master Thread Checkpoint
  2. FLUSH_LRU_LIST Checkpoint
  3. Async/Sync Flush Checkpoint
  4. Dirty Page too much Checkpoint
Master Thread Checkpoint

在Master Thread中,會以每秒或者每10秒一次的頻率,將部分髒頁從內存中刷新到磁盤,這個過程是
異步的。正常的用戶線程對數據的操作不會被阻塞。

FLUSH_LRU_LIST Checkpoint

FLUSH_LRU_LIST checkpoint是在單獨的page cleaner線程中執行的。
MySQL對緩存的管理是通過buffer pool中的LRU列表實現的,LRU 空閒列表中要保留一定數量的
空閒頁面,來保證buffer pool中有足夠的空閒頁面來相應外界對數據庫的請求。
當這個空間頁面數量不足的時候,發生FLUSH_LRU_LIST checkpoint。
空閒頁的數量由innodb_lru_scan_depth參數表來控制的,因此在空閒列表頁面數量少於配置的
值的時候,會發生checkpoint,剔除部分LRU列表尾端的頁面。

Async/Sync Flush Checkpoint

Async/Sync Flush checkpoint是在單獨的page cleaner線程中執行的。
Async/Sync Flush checkpoint 發生在重做日誌不可用的時候,將buffer pool中的一部分髒頁刷
新到磁盤中,在髒頁寫入磁盤之後,事物對應的重做日誌也就可以釋放了。
關於redo_log文件的的大小,可以通過 innodb_log_file_size 來配置。

對於是執行Async Flush checkpoint還是Sync Flush checkpoint,由checkpoint_age以及
async_water_mark和sync_water_mark來決定。

async_water_mark=75%*innodb_log_file_size
sync_water_mark=90%*innodb_log_file_size
  1. 當checkpoint_age<sync_water_mark的時候,無需執行Flush checkpoint。也就說,redo
    log剩餘空間超過25%的時候,無需執行Async/Sync Flush checkpoint。
  2. 當async_water_mark<checkpoint_age<sync_water_mark的時候,執行Async Flush
    checkpoint,也就說,redo log剩餘空間不足25%,但是大於10%的時候,執行Async Flush
    checkpoint,刷新到滿足條件1
  3. 當checkpoint_age>sync_water_mark的時候,執行sync Flush checkpoint。也就說,redo
    log剩餘空間不足10%的時候,執行Sync Flush checkpoint,刷新到滿足條件1。

在mysql 5.6之後,不管是Async Flush checkpoint還是Sync Flush checkpoint,都不會阻
塞用戶的查詢進程。

由於磁盤是一種相對較慢的存儲設備,內存與磁盤的交互是一個相對較慢的過程
由於innodb_log_file_size定義的是一個相對較大的值,正常情況下,由前面兩種checkpoint刷新
髒頁到磁盤,在前面兩種checkpoint刷新髒頁到磁盤之後,髒頁對應的redo log空間隨即釋放,
一般不會發生Async/Sync Flush checkpoint。同時也要意識到,爲了避免頻繁低發生Async/Sync
Flush checkpoint,也應該將innodb_log_file_size配置的相對較大一些。

Dirty Page too much Checkpoint

Dirty Page too much Checkpoint是在Master Thread 線程中每秒一次的頻率實現的。
Dirty Page too much 意味着buffer pool中的髒頁過多,執行checkpoint髒頁刷入磁盤,保證
buffer pool中有足夠的可用頁面。
Dirty Page 由innodb_max_dirty_pages_pct配置,innodb_max_dirty_pages_pct的默認值在
innodb 1.0之前是90%,之後是75%

重做日誌落盤

InnoDB存儲引擎會首先將重做日誌信息先放入重做日誌緩衝中,然後再按照一定頻率將其刷新到
重做日誌文件。重做日誌緩衝一般不需要設置得很大,因爲一般情況每一秒鐘都會講重做日誌緩 沖刷新到日誌文件中。可通過配置參數
innodb_log_buffer_size 控制,默認爲8MB。

操作系統的文件系統是帶有緩存的,當InnoDB向磁盤寫入數據時,有可能只是寫入到了文件系統的緩
存中,沒有真正的“落袋爲安”。
InnoDB的innodb_flush_log_at_trx_commit屬性可以控制每次事務提交時InnoDB的行爲。
當屬性值爲0時,事務提交時,不會對重做日誌進行寫入操作,而是等待主線程按時寫入;
當屬性值爲1時,事務提交時,會將重做日誌寫入文件系統緩存,並且調用文件系統的fsync,將文
件系統緩衝中的數據真正寫入磁盤存儲,確保不會出現數據丟失;
當屬性值爲2時,事務提交時,也會將日誌文件寫入文件系統緩存,但是不會調用fsync,而是讓文
件系統自己去判斷何時將緩存寫入磁盤。

innodb_flush_log_at_commit是InnoDB性能調優的一個基礎參數,涉及InnoDB的寫入效率和數
據安全。當參數值爲0時,寫入效率最高,但是數據安全最低;參數值爲1時,寫入效率最低,但
是數據安全最高;參數值爲2時,二者都是中等水平。一般建議將該屬性值設置爲1,以獲得較高
的數據安全性,而且也只有設置爲1,才能保證事務的持久性。

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