寫關注(Write Concern)描述了向單獨的mongod、副本集或分片叢集進行寫操作時,MongoDB 所要求的確認級別。在分片叢集中,mongos例項會將寫關注傳遞給分片。
注:
對於多文件事務,應在事務級別而非單個操作級別設定寫關注。不要為事務中的單個寫操作明確設定寫關注。
如果為多文件事務指定了 "majority" 寫關注,而事務未能複製到計算出的多數副本整合員,那麼事務可能不會立即在副本整合員上回滾。副本集會逐漸最終保持一致。事務總是在所有副本整合員上應用或回滾。
副本集和分片群集支援設定全域性預設寫關注。未指定顯式寫關注的操作會繼承全域性預設寫關注設定。
寫關注說明
寫關注包含以下欄位:
{ w: <value>, j: <boolean>, wtimeout: <number> }
其中:
· w選項用於請求確認寫入操作已傳播到指定數量的mongod例項或帶有指定標記的mongod例項。如果沒有指定該值,會使用預設的寫關注設定。如果使用 setDefaultRWConcern 設定預設寫關注,則必須指定w欄位值。
· j選項用於請求確認寫入操作已寫入磁碟日誌
· wtimeout選項,用於指定一個時間限制,防止寫操作無限期阻塞。單位是毫秒。只有在 w 的值大於 1 的時候,才有效。超時後,寫操作會報錯,即使寫關注會最終實現一致。
w: <value> 格式中,可以設定的值有:"majority"、<number>、<自定義寫關注的名稱>
從 MongoDB 5.0 開始,預設的寫關注是 w: majority 。不過,包含仲裁節點的時候,要另外考慮:副本集的投票多數機制為 1 加上投票成員數的一半,四捨五入。如果攜帶資料的投票成員數不超過投票多數,則預設寫入關注點為{ w: 1 } ;在所有其他情況下,預設寫關注點為{ w: “majority” } 。
具體來說,MongoDB 使用以下公式來確定預設寫關注:
if [ (#arbiters > 0) AND (#non-arbiters <= majority(#voting-nodes)) ] defaultWriteConcern = { w: 1 } else defaultWriteConcern = { w: "majority" }
ACK 的行為
w: <value>, j: <boolean> 決定了 mongod 例項對寫操作的 ack 行為。
單節點 mongod 例項的ack
對於單節點的例項,寫操作的 ack 發生在記憶體中完成應用,或寫入磁碟上的 journal 之後。下表列出了相應寫關注設定的 ack 行為:
j未指定 |
j:true |
j:false |
|
w: 1 |
In memory |
On-disk journal |
In memory |
w: "majority" |
On-disk journal(如果開啟了) |
On-disk journal |
In memory |
副本集 mongod 例項的ack
j未指定 |
j:true |
j:false |
|
w: <number> |
In memory |
On-disk journal |
In memory |
w: "majority" |
取決與writeConcernMajorityJournalDefault的設定: ·true(預設值):On-disk journal ·false:In memory |
On-disk journal |
In memory |
從 MongoDB 8.0 開始,{ w: "majority" }寫入會在大多數資料成員持久寫入 oplog 條目後返回確認。然後,成員再從本地 oplog 讀取更改時非同步應用這些更改。在早期版本中,MongoDB 會等到成員應用寫入後才返回確認。
在{ w: "majority" }寫入返回確認後立即對輔助庫進行查詢,可能會在輔助庫應用寫入更改之前從集合中讀取內容。
如果應用程式從輔助資料集讀取資料,並要求立即訪問{ w: "majority" }寫入中的更改,請在因果一致的會話中執行這些操作。
local 資料庫不支援寫關注設定。