2016-05-30 44 views
2

我們有一個客戶端在兩個文檔上連續寫入(使用{w:1})。 例如,原件可能是:在兩個文檔上寫入時,Mongodb在副本集上的最終一致性

{_id: "a", value: 0}{_id: "b", value: 0}

和客戶端更新文件「a」到{_id: "a", value: 1},然後,更新完成後,客戶端更新文件「B」至{_id: "b", value: 1}後。

第二個客戶事後撥打find({})。第二個客戶端從輔助服務器讀取數據,可能尚未收到所有更改。 很明顯,它可以閱讀以下狀態:

  • {_id:"a",value:0}{_id:"b",value:0}
  • {_id:"a",value:1}{_id:"b",value:0}
  • {_id:"a",value:1}{_id:"b",value:1}

這些都對主要的 「真實」 的狀態(在某個時刻過去)。

第二個客戶端可以看到如下狀態:{_id:"a",value:0}{_id:"b",value:1}?注意這個狀態從來就不存在於小學。

P.S. 解釋here說:

二級工具......它們出現在OPLOG順序應用的寫操作。

這是否意味着輔助用戶按照他們在主服務器上更新的順序更改他們的文檔?

P.S. find遊標是否「凍結」了他們正在讀取的文檔的狀態(即忽略光標創建後所做的更改)?如果我使用find(...).sort({_id:-1})或者文檔「a」的id是「c」(即大於「b」),情況會不同嗎?

感謝

回答

1

第一個問題:是的,輔助操作的執行順序與主輔助操作的順序相同。所有操作都記錄在oplog中。 oplog本身不是執行查詢的日誌(即updateMany()),但是必須對實際文檔執行什麼操作,以使操作變得冪等。

關於遊標操作。在遍歷遊標時可能會發生文檔移動或更新。甚至可能發生,如果在更新過程中索引或存儲位置發生更改,則同一文檔會在光標上出現兩次。

有一個特殊的snapshot模式,提供某種隔離的,但它有一定的侷限性,即它不能與分片

+0

謝謝你的光標解釋。 – Oren

0

如果我們documnet通過序列的主更新

  1. 改變
  2. 變化率B
  3. 變動c

然後次級將更新文件具有相同序列號:

  1. 變化甲

    documnet可以在沒有其它的變化來讀取施加

  2. 變化乙

    documnet可以讀取而不其他改變施加

  3. 變動c

對於鎖定see this,因爲mongo可以優化操作順序,即使文檔更新被啓動,也可以允許讀取操作順序。

+0

怎麼樣'find'操作中使用?如果'find'按順序找到兩個文檔「a」和「b」,它可以在更改前返回文檔「a」,並在更改後返回文檔「b」? – Oren

+0

@Oren - 所有時間都與'W:1'連接,所以如果在次要處理'change B'之前'find'將會失敗,那麼'change A'會被髮送回客戶端。 – profesor79