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

oplog is not idempotent for array operators, which could lead to silent data corruption (without journalling)

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Major - P3 Major - P3
    • 2.3.0
    • Affects Version/s: 1.8.2
    • Component/s: Replication
    • None
    • ALL

      I was looking at bug SERVER-3217, and upon seeing the structure of the oplog I became worried that the only "guarantee" for idempotence might be a mere check on the size of the array on $push/$pop. This is certainly not enough to ensure idempotence.

      See, for example, the following code:

      // initialize db
      db.foo.save(

      { x: ["a", "b"] }

      )

      // do some sequence of operations:
      db.foo.update({}, {$pull: { x: "c" }})
      db.foo.update({}, {$push: { x: "c" }})
      db.foo.update({}, {$addToSet: { x: "d" }})
      db.foo.update({}, {$pull: { x: "b" }})
      db.foo.update({}, {$pop: { x: 1 }})

      // we now have

      { x: ["a", "c"] }

      in the database

      Now, when replaying the last 5 operations from the oplog, the $push and the $pop would be ignored as their $size does not match, but all other 3 operations would still occur:

      db.foo.update({}, {$pull: { x: "c" }})
      db.foo.update({}, {$addToSet: { x: "d" }})
      db.foo.update({}, {$pull: { x: "b" }})

      The database now contains

      { x: ["a", "d"] }

      , which is incorrect.

      So this is pretty dramatic. I really think you ought to be looking for a formal proof of the idempotence of the oplog system if you are to make any claims about durability or even consistency of the data stored in MongoDB.

            Assignee:
            alerner Alberto Lerner
            Reporter:
            makely makely
            Votes:
            1 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: