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)

    XMLWordPrintableJSON

Details

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: Major - P3 Major - P3
    • 2.3.0
    • 1.8.2
    • Replication
    • None
    • ALL

    Description

      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.

      Attachments

        Activity

          People

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

            Dates

              Created:
              Updated:
              Resolved: