MongoDB的日誌Journaling詳解

chenfeng發表於2015-12-24

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儲存以下原始操作:


1. 文件插入或更新


2. 索引修改


3. 名稱空間檔案後設資料的修改


4. 建立和者刪除資料庫或關聯的資料檔案

當發生寫操作,MongoDB首先寫入資料到記憶體中的private檢視,然後批次複製寫操作到journal日誌檔案。寫個journal日誌實體來用描述寫操作改變資料檔案的哪些位元組。


MongoDB接下來執行journal的寫操作到shared檢視。此時,shared檢視與磁碟資料檔案不一樣。


預設每60s鍾,MongoDB請求作業系統將shared檢視刷入到磁碟。使資料檔案更新到最新的寫入狀態。如果系統記憶體資源不足的時候,作業系統會選擇以更高的頻率刷入shared檢視到磁碟。


MongoDB刷入資料檔案完成後,會通知journal日誌已經刷入。一旦journal日誌檔案只包含全部刷入的寫操作,不再用於恢復,MongoDB會將它刪除或者作為一個新的日誌檔案再次使用。


作為journaling機制的一部分,MongoDB會例行性請求作業系統重新將shared檢視對映到private檢視,為了節省實體記憶體。一旦發生重對映,作業系統能夠識別到可以在private檢視和shared檢視共享的記憶體頁對映。

如果開啟了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中非常重要的一項功能,類似於關聯式資料庫中的事務日誌。Journaling能夠使MongoDB資料庫由於意外故障後快速恢復。MongoDB2.0版本後預設開啟了Journaling日誌功能,mongod例項每次啟動時都會檢查journal日誌檔案看是否需要恢復。由於提交journal日誌會產生寫入阻塞,所以它對寫入的操作有效能影響,但對於讀沒有影響。在生產環境中開啟Journaling是很有必要的。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/15498/viewspace-1934310/,如需轉載,請註明出處,否則將追究法律責任。

相關文章