From a15dbb65cab3cc896f7dcda75cd471e3783b9bc4 Mon Sep 17 00:00:00 2001 From: Benety Goh Date: Thu, 12 Mar 2015 18:08:26 -0400 Subject: [PATCH] SERVER-17634 do not apply replicated insert operations on missing collections --- jstests/auth/user_defined_roles_on_secondaries.js | 10 ++++++++++ jstests/core/apply_ops1.js | 12 ++++++++++++ jstests/tool/oplog1.js | 2 ++ src/mongo/db/repl/oplog.cpp | 4 ++++ 4 files changed, 28 insertions(+) diff --git a/jstests/auth/user_defined_roles_on_secondaries.js b/jstests/auth/user_defined_roles_on_secondaries.js index 1ef357fb2d8..541f8f4440b 100644 --- a/jstests/auth/user_defined_roles_on_secondaries.js +++ b/jstests/auth/user_defined_roles_on_secondaries.js @@ -149,6 +149,11 @@ rstest.nodes.forEach(function (node) { // Verify that applyOps commands propagate. // NOTE: This section of the test depends on the oplog and roles schemas. assert.commandWorked(rstest.getMaster().getDB("admin").runCommand({ applyOps: [ + { + op: "c", + ns: "admin.$cmd", + o: { create: "system.roles" } + }, { op: "i", ns: "admin.system.roles", @@ -176,6 +181,11 @@ assert.commandWorked(rstest.getMaster().getDB("admin").runCommand({ applyOps: [ ns: "admin.$cmd", o: { dropDatabase: 1 } }, + { + op: "c", + ns: "admin.$cmd", + o: { create: "system.roles" } + }, { op: "i", ns: "admin.system.roles", diff --git a/jstests/core/apply_ops1.js b/jstests/core/apply_ops1.js index bc34b9e92bf..11948b34d33 100644 --- a/jstests/core/apply_ops1.js +++ b/jstests/core/apply_ops1.js @@ -52,12 +52,24 @@ ); assert.eq(0, t.find().count() , "Non-zero amount of documents in collection to start"); + assert.commandFailed(db.adminCommand( + {applyOps: [{"op": "i", "ns": t.getFullName(), "o": {_id: 5, x: 17}}]} + ), + "Applying an insert operation on a non-existent collection should fail"); + + assert.commandWorked(db.createCollection(t.getName())); var a = db.adminCommand( {applyOps: [{"op": "i", "ns": t.getFullName(), "o": {_id: 5, x: 17}}]} ); assert.eq(1, t.find().count() , "Valid insert failed"); assert.eq(true, a.results[0], "Bad result value for valid insert"); + a = db.adminCommand( + {applyOps: [{"op": "i", "ns": t.getFullName(), "o": {_id: 5, x: 17}}]} + ); + assert.eq(1, t.find().count() , "Duplicate insert failed"); + assert.eq(true, a.results[0], "Bad result value for duplicate insert"); + var o = {_id: 5, x: 17}; assert.eq(o , t.findOne() , "Mismatching document inserted."); diff --git a/jstests/tool/oplog1.js b/jstests/tool/oplog1.js index e9a002bfb65..01cb52db2bd 100644 --- a/jstests/tool/oplog1.js +++ b/jstests/tool/oplog1.js @@ -11,6 +11,8 @@ output = db.output doc = { _id : 5 , x : 17 }; +assert.commandWorked(db.createCollection(output.getName())); + db.oplog.insert( { ts : new Timestamp() , "op" : "i" , "ns" : output.getFullName() , "o" : doc } ); assert.eq( 0 , output.count() , "before" ) diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp index 7d4eace3154..b97f447eb2a 100644 --- a/src/mongo/db/repl/oplog.cpp +++ b/src/mongo/db/repl/oplog.cpp @@ -498,6 +498,10 @@ namespace { // do upserts for inserts as we might get replayed more than once OpDebug debug; + uassert(ErrorCodes::NamespaceNotFound, str::stream() << + "Failed to apply insert due to missing collection: " << op.toString(), + collection); + // No _id. // This indicates an issue with the upstream server: // The oplog entry is corrupted; or