運行MongoDB若是開啓了journaling日誌功能,MongoDB先在內存保存寫操做,並記錄journaling日誌到磁盤,而後纔會把數據改變刷入到磁盤上的數據文件。爲了保證journal日誌文件的一致性,寫日誌是一個原子操做。本文將討論MongoDB中journaling日誌的實現機制。數據庫
若是開啓了journal日誌功能,MongoDB會在數據目錄下建立一個journal
文件夾,用來存放預寫重放日誌。同時這個目錄也會有一個last-sequence-number
文件。若是MongoDB安全關閉的話,會自動刪除此目錄下的全部文件,若是是崩潰致使的關閉,不會刪除日誌文件。在MongoDB進程重啓的過程當中,journal日誌文件用於自動修復數據到一個一致性的狀態。安全
journal日誌文件是一種往文件尾不停追加內容的文件,它命名以j._
開頭,後面接一個數字(從0開始)做爲序列號。若是文件超過1G大小,MongoDB會新建一個journal文件j._1
。只要MongoDB把特定日誌中的全部寫操做刷入到磁盤數據文件,將會刪除此日誌文件。由於數據已經持久化,再也不須要用它來重放恢復數據了。journal日誌文件通常狀況下只會生成兩三個,除非你每秒有大量的寫操做發生。性能
若是你須要的話,你可使用storage.smallFiles
參數來配置journal日誌文件的大小。好比配置爲128M
。操作系統
Journaling功能用到了MongoDB存儲層數據集內部的兩個視圖。日誌
shared
視圖保存數據修改操做,用於刷入到磁盤數據文件。shared
視圖是MongoDB中惟一訪問磁盤數據文件的視圖。mongod
進程請求操做系統把磁盤數據文件映射到虛擬內存的shared
視圖。操做系統只是映射數據與內存關係,並不立刻加載數據到內存。當查詢須要的時候,纔會加載數據到內存,即按需加載。code
private
視圖存儲用於查詢操做的數據。同時private
視圖也是MongoDB執行寫操做的第一個地方。一旦journal日誌提交完成,MongoDB會複製private
視圖中的改變到shared
視圖,再經過shared
視圖將數據刷入到磁盤數據文件。索引
journal
視圖是一個用來保證新的寫操做的磁盤視圖。當MongoDB在private
視圖執行完寫操做後,在數據刷入磁盤以前,會先記錄journal
日誌。journal
日誌保證了持久性。若是mongod
實例在數據刷入磁盤以前崩潰,重啓過程當中journal
日誌會重放並寫入shared
視圖,最終刷入磁盤持久化。進程
MongoDB採用group commits
方式將寫操做批量複製到journal
日誌文件中。group commits
提交方式可以最小化journal日誌機制對性能的影響。所以group commits
方式在提交過程當中必須阻塞全部寫入。commitIntervalMs
參數能夠用於配置日誌提交的頻率,默認是100ms。事務
Journaling存儲如下原始操做:內存
當發生寫操做,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是頗有必要的。