MongoDB的Journaling日志機制

jopen 9年前發布 | 36K 次閱讀 MongoDB NoSQL數據庫

Journaling日志機制


運行MongoDB如果開啟了journaling日志功能,MongoDB先在內存保存寫操作,并記錄journaling日志到磁盤,然后才會把數據改變刷入到磁盤上的數據文件。為了保證journal日志文件的一致性,寫日志是一個原子操作。本文將討論MongoDB中journaling日志的實現機制。

Journal日志文件

如果開啟了journal日志功能,MongoDB會在數據目錄下創建一個journal文件夾,用來存放預寫重放日志。同時這個目錄也會有一個last-sequence-number文件。如果MongoDB安全關閉的話,會自動刪除此目錄下的所有文件,如果是崩潰導致的關閉,不會刪除日志文件。在MongoDB進程重啟的過程中,journal日志文件用于自動修復數據到一個一致性的狀態。

journal日志文件是一種往文件尾不停追加內容的文件,它命名以j._開頭,后面接一個數字(從0開始)作為序列號。如果文件超過1G大小,MongoDB會新建一個journal文件j._1。只要MongoDB把特定日志中的所有寫操作刷入到磁盤數據文件,將會刪除此日志文件。因為數據已經持久化,不再需要用它來重放恢復數據了。journal日志文件一般情況下只會生成兩三個,除非你每秒有大量的寫操作發生。

如果你需要的話,你可以使用storage.smallFiles參數來配置journal日志文件的大小。比如配置為128M。

Journaling機制的存儲視圖

Journaling功能用到了MongoDB存儲層數據集內部的兩個視圖。

shared視圖保存數據修改操作,用于刷入到磁盤數據文件。shared視圖是MongoDB中唯一訪問磁盤數據文件的視圖。mongod進程請求操作系統把磁盤數據文件映射到虛擬內存的shared視圖。操作系統只是映射數據與內存關系,并不馬上加載數據到內存。當查詢需要的時候,才會加載數據到內存,即按需加載。

private視圖存儲用于查詢操作的數據。同時private視圖也是MongoDB執行寫操作的第一個地方。一旦journal日志提交完成,MongoDB會復制private視圖中的改變到shared視圖,再通過shared視圖將數據刷入到磁盤數據文件。

journal視圖是一個用來保證新的寫操作的磁盤視圖。當MongoDB在private視圖執行完寫操作后,在數據刷入磁盤之前,會先記錄journal日志。journal日志保證了持久性。如果mongod實例在數據刷入磁盤之前崩潰,重啟過程中journal日志會重放并寫入shared視圖,最終刷入磁盤持久化。

Journaling如何紀錄寫操作

MongoDB采用group commits方式將寫操作批量復制到journal日志文件中。group commits提交方式能夠最小化journal日志機制對性能的影響。因此group commits方式在提交過程中必須阻塞所有寫入。commitIntervalMs參數可以用于配置日志提交的頻率,默認是100ms。

Journaling存儲以下原始操作:

  • 文檔插入或更新
  • 索引修改
  • 命名空間文件元數據的修改
  • 創建和者刪除數據庫或關聯的數據文件
  • </ul>

    當發生寫操作,MongoDB首先寫入數據到內存中的private視圖,然后批量復制寫操作到journal日志文件。寫個journal日志實體來用描述寫操作改變數據文件的哪些字節。

    MongoDB接下來執行journal的寫操作到shared視圖。此時,shared視圖與磁盤數據文件不一樣。

    默認每60s鐘,MongoDB請求操作系統將shared視圖刷入到磁盤。使數據文件更新到最新的寫入狀態。如果系統內存資源不足的時候,操作系統會選擇以更高的頻率刷入shared視圖到磁盤。

    MongoDB刷入數據文件完成后,會通知journal日志已經刷入。一旦journal日志文件只包含全部刷入的寫操作,不再用于恢復,MongoDB會將它刪除或者作為一個新的日志文件再次使用。

    作為journaling機制的一部分,MongoDB會例行性請求操作系統重新將shared視圖映射到private視圖,為了節省物理內存。一旦發生重映射,操作系統能夠識別到可以在private視圖和shared視圖共享的內存頁映射。

    小結

    Journaling是MongoDB中非常重要的一項功能,類似于關系數據庫中的事務日志。Journaling能夠使MongoDB數據庫由于意外故障后快速恢復。MongoDB2.0版本后默認開啟了Journaling日志功能,mongod實例每次啟動時都會檢查journal日志文件看是否需要恢復。由于提交journal日志會產生寫入阻塞,所以它對寫入的操作有性能影響,但對于讀沒有影響。在生產環境中開啟Journaling是很有必要的。

    </div> 來自:http://my.oschina.net/jockchou/blog/470388

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!