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

Allow applyOps to ignore unique index constraints

    • Type: Icon: Improvement Improvement
    • Resolution: Won't Fix
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: Write Ops
    • None
    • Major Change

      Since unique index constraints are relaxed in other places where batches of operations are applied (atomically), eg. initial sync, recovering, rollback, etc; they should also be relaxed when applying a batch of operations given to applyOps.

      This means that the following should succeed:

      var t = db.test;
      t.drop();
      t.ensureIndex( { a: 1}, { unique: true } );
      t.insert( { _id : 1, a : 2 } );
      t.insert( { _id : 2, a : 1 } );
      var op1 = { "ts" : Timestamp( 1438051519, 1 ), "h" : NumberLong(-4881641317324516364), "v" : 2, "op" : "i", "ns" : "test.test", "o" : { "_id" : 1, "a" : 1 } };
      var op2 = { "ts" : Timestamp( 1438051521, 1 ), "h" : NumberLong(6481857659867173805), "v" : 2, "op" : "u", "ns" : "test.test", "o2" : { "_id" : 1 }, "o" : { "$set" : { "a" : 2 } } };
      var op3 = { "ts" : Timestamp( 1438051524, 1 ), "h" : NumberLong(4061210955299695112), "v" : 2, "op" : "i", "ns" : "test.test", "o" : { "_id" : 2, "a" : 1 } };
      t.getDB().runCommand( { applyOps: [ op1, op2, op3 ] } );
      

      Current behaviour is that it fails on the first operation:

      > t.getDB().runCommand( { applyOps: [ op1, op2, op3 ] } );
      {
              "errmsg" : "exception: E11000 duplicate key error index: test.test.$a_1 dup key: { : 1.0 }",
              "code" : 11000,
              "ok" : 0
      }
      

      If there are still duplicates in the db at the end of the batch (for example, by passing just op1 in the command above), then ideally this should be flagged somehow (since the db has entered an erroneous state).

      The best case would be for the effects of the entire batch to be undone, and the applyOps command to fail. Unfortunately the problem is that by time the end of the batch has been reached, the operations have already been applied and can't easily be undone. This means that actually rolling back is likely to be impossible.

      This may not be a problem if subsequent applyOps batches are going to correct the problem (and there will be no other intervening writes). Since this is not certain to occur it would still probably be best to issue a warning or (different) error message to alert the user of the situation (ie. that there are now duplicates in the db).

            Assignee:
            Unassigned Unassigned
            Reporter:
            kevin.pulo@mongodb.com Kevin Pulo
            Votes:
            0 Vote for this issue
            Watchers:
            9 Start watching this issue

              Created:
              Updated:
              Resolved: