Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-37171

Inability to read own writes after they were acknowledged

    • Type: Icon: Bug Bug
    • Resolution: Works as Designed
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: Replication
    • Labels:
      None
    • Replication
    • ALL
    • Hide

      Repro for #1:

      (function() {
      
      function getOplogLastApplied(node) {
       return node.getDB("local").oplog.rs.find().sort(\{$natural: -1})[0]["ts"];
       }
      
      let rst = ReplSetTest(\{name: "funWithWrites", nodes: 2});
       rst.startSet();
       rst.initiate();
      
      rst.awaitNodesAgreeOnPrimary();
       let primary = rst.getPrimary();
       let secondary = rst.getSecondary();
      
      let primaryBefore = getOplogLastApplied(primary);
       let secondaryBefore = getOplogLastApplied(secondary);
      
      assert.eq(primaryBefore, secondaryBefore);
      
      assert.writeOK(primary.getDB("test").w2write.insert(\{"a": 1}, \{w: 2}));
      
      let primaryAfter = getOplogLastApplied(primary);
       let secondaryAfter = getOplogLastApplied(secondary);
      
      print("ts before write: " + primaryBefore);
       print("ts after write: " + primaryAfter);
      
      // Can fail
       assert.eq(primaryAfter, secondaryAfter);
      
      })();
      

      Repro for #2:

      (function() {
      
      function getCommittedOptimeFromPrimary(primary) {
       return assert.commandWorked(primary.adminCommand(\{replSetGetStatus: 1}))
       .optimes.lastCommittedOpTime.ts;
       }
      
      let rst = ReplSetTest(\{name: "funWithWrites", nodes: 2});
       rst.startSet();
       rst.initiate();
      
      rst.awaitNodesAgreeOnPrimary();
       let primary = rst.getPrimary();
       let secondary = rst.getSecondary();
      
      let commitedBefore = getCommittedOptimeFromPrimary(primary);
       print("committed optime before write: " + commitedBefore);
      
      assert.writeOK(primary.getDB("test").w2write.insert(\{"a": 1}, \{w: 'majority'}));
      
      let committedAfter = getCommittedOptimeFromPrimary(primary);
      
      // Can fail
       assert.neq(commitedBefore, committedAfter);
      
      })();
      
      Show
      Repro for #1: (function() { function getOplogLastApplied(node) { return node.getDB("local").oplog.rs.find().sort(\{$natural: -1})[0]["ts"]; } let rst = ReplSetTest(\{name: "funWithWrites", nodes: 2}); rst.startSet(); rst.initiate(); rst.awaitNodesAgreeOnPrimary(); let primary = rst.getPrimary(); let secondary = rst.getSecondary(); let primaryBefore = getOplogLastApplied(primary); let secondaryBefore = getOplogLastApplied(secondary); assert.eq(primaryBefore, secondaryBefore); assert.writeOK(primary.getDB("test").w2write.insert(\{"a": 1}, \{w: 2})); let primaryAfter = getOplogLastApplied(primary); let secondaryAfter = getOplogLastApplied(secondary); print("ts before write: " + primaryBefore); print("ts after write: " + primaryAfter); // Can fail assert.eq(primaryAfter, secondaryAfter); })(); Repro for #2: (function() { function getCommittedOptimeFromPrimary(primary) { return assert.commandWorked(primary.adminCommand(\{replSetGetStatus: 1})) .optimes.lastCommittedOpTime.ts; } let rst = ReplSetTest(\{name: "funWithWrites", nodes: 2}); rst.startSet(); rst.initiate(); rst.awaitNodesAgreeOnPrimary(); let primary = rst.getPrimary(); let secondary = rst.getSecondary(); let commitedBefore = getCommittedOptimeFromPrimary(primary); print("committed optime before write: " + commitedBefore); assert.writeOK(primary.getDB("test").w2write.insert(\{"a": 1}, \{w: 'majority'})); let committedAfter = getCommittedOptimeFromPrimary(primary); // Can fail assert.neq(commitedBefore, committedAfter); })();
    • Repl 2018-10-08

      #1: One such scenario is the following: we issue a w:2 write, it gets confirmed, then we do a direct find on the secondary oplog, but are unable to observe the write.

       #2: A different but possibly related scenario is issuing a w:majority write, then calling ReplSetGetStatus on the primary and not observing the commit point advance.

      Both of these can be observed with no other writes happening in the system (e.g. no-op writer turned off).

            Assignee:
            backlog-server-repl [DO NOT USE] Backlog - Replication Team
            Reporter:
            vesselina.ratcheva@mongodb.com Vesselina Ratcheva (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: