禁用日誌的 MongoDB 磁碟操作
假設 MongoDB 3.6,使用 WiredTiger,禁用日誌:
mongod如何將數據寫入硬碟?它對每個文件執行寫操作?每塊?同樣:閱讀怎麼樣?另外:這些讀寫是隨機的還是順序的?
更進一步:寫入日誌文件期間的寫入是否類似於創建快照時的寫入?
問題的進一步解釋:我試圖限制執行 MongoDB 的 Docker 容器對硬碟驅動器的使用,所以我開始按照本指南對磁碟進行基準測試:binarylane.com - 如何對磁碟 I/O 進行基準測試 。它指出
同樣,數據庫和許多其他程序將讀取非常小的數據塊 - 4 KB 是一個很好的工作估計。
我想知道這個假設是否適用於 MongoDB。
WiredTiger 有兩種主要方法可以確保數據的持久性:日誌和檢查點。
檢查點儲存整個數據庫的有效且一致的狀態。如果伺服器因任何原因崩潰,它可以從最後一個檢查點以一致的狀態重新啟動。WiredTiger 預設每 60 秒檢查一次數據庫。
日誌儲存發生在檢查點之間的寫入。如果數據庫在檢查點之間崩潰,日誌數據將在最後一個已知的良好檢查點之上重放。日誌每 50 毫秒持久保存到磁碟。與檢查點相比,日誌過程被優化為更輕量級(而且它的工作量也少了很多),因此它通常比檢查點快得多。
mongod
如果禁用日誌,則在獨立模式或副本集模式下執行的行為略有不同:
- MongoDB 3.6.4 Standalone with journaling disabled:只有整個數據庫的完整狀態才會在每個檢查點寫入磁碟。也就是說,如果您的數據庫在檢查點之間崩潰,您可能會失去最後 60 秒的寫入(如果使用預設檢查點計時值)。
- 禁用日誌的 MongoDB 3.6.4 副本集:根據設計,副本集需要更高的持久性,因為它必須記錄 oplog 中的每個操作並確保 oplog 安全持久化。因此,它將改為在每次寫入時執行檢查點。這將極大地減慢副本集的速度。
您通過禁用日記功能做出的權衡:
- 在獨立部署中,由於數據庫的主要目標是持久化數據,因此限制磁碟使用(空間或 IOPS)將導致在允許的寫入之間失去更多數據。但是,不建議出於生產目的執行獨立的 MongoDB。
- 在副本集中,由於需要持久化 oplog,寫入過程會大大減慢。這也將使部署使用更多的磁碟 IOPS。在 MongoDB 的未來版本中,將不允許執行沒有日誌的副本集(請參閱SERVER-30347)。
有關日記的更多資訊,請參閱日記過程頁面。
mongod如何將數據寫入硬碟?它對每個文件執行寫操作?每塊?同樣:閱讀怎麼樣?另外:這些讀寫是隨機的還是順序的?
作為 MongoDB BOL Here Journaling Process
Changed in version 3.2
。使用**
journaling
**,WiredTiger
為每個客戶端啟動的write
操作創建一個日誌記錄。日誌記錄包括write operations
由初始寫入引起的任何內部。例如,對集合中文件的更新可能會導致對索引的修改;WiredTiger
創建一個single journal record
包含更新操作及其關聯的索引修改的。MongoDB 將 WiredTiger 配置為使用記憶體緩衝來儲存日誌記錄。執行緒協調分配和復製到它們的緩衝區部分。
All journal records up to 128 kB are buffered
.對於日誌文件,MongoDB 在目錄下創建一個名為 journal 的子目錄
dbPath
。WiredTiger 日誌文件具有以下格式的名稱,其中**WiredTigerLog.<sequence>
數字從.<sequence>``zero-padded
0000000001
**日記文件包含一條記錄
per each write operation
。每條記錄都有一個唯一的標識符。MongoDB
配置WiredTiger
為對日誌數據使用 snappy 壓縮。**
Note :
為了在發生故障時提供持久性,MongoDB 使用預寫日誌記錄到磁碟journal
**文件。正如 MongoDB在 Here A中記錄的那樣**
sequential
,binary transaction log
用於在硬關機時使數據庫進入有效狀態。日誌首先將數據寫入日誌,然後再寫入核心數據文件。預設情況下,MongoDB 為64-bit
**建構MongoDB version 2.0
和更新的版本啟用日記功能。日誌文件是預先分配的,並作為文件存在於數據目錄中。更進一步:寫入日誌文件期間的寫入是否類似於創建快照時的寫入?
如果將其放置在與數據文件
journal
不同的位置filesystem
,則不能filesystem
單獨使用快照來擷取dbPath目錄的有效備份。在這種情況下,用於fsyncLock()
確保在快照之前和fsyncUnlock()
快照完成後數據庫文件是一致的。
Note :
db.fsyncUnlock()是一個管理操作。