diff options
author | matt dannenberg <matt.dannenberg@10gen.com> | 2015-06-16 08:06:18 -0400 |
---|---|---|
committer | matt dannenberg <matt.dannenberg@10gen.com> | 2015-06-17 13:22:36 -0400 |
commit | 7523229c8dda361a10a42e622fc04441f5011fb6 (patch) | |
tree | 9a28af37c9bc501f3c393d3b2a3cd8b8bdabecf2 | |
parent | bdf6a4b8af528241818ce03ce2483ac3c0c2aeff (diff) | |
download | mongo-7523229c8dda361a10a42e622fc04441f5011fb6.tar.gz |
SERVER-18962 do not replicate metadata operations pertaining to system.profile
-rw-r--r-- | jstests/replsets/system_profile.js | 48 | ||||
-rw-r--r-- | src/mongo/db/op_observer.cpp | 28 |
2 files changed, 71 insertions, 5 deletions
diff --git a/jstests/replsets/system_profile.js b/jstests/replsets/system_profile.js new file mode 100644 index 00000000000..592accb43b8 --- /dev/null +++ b/jstests/replsets/system_profile.js @@ -0,0 +1,48 @@ +// This tests that metadata commands run against the system.profile collection are not replicated +// to the secondary. + +(function() { + "use strict"; + var rst = new ReplSetTest({nodes: 2}); + rst.startSet(); + rst.initiate(); + rst.awaitReplication(); + + var getLatestOp = function() { + return primaryDB.getSiblingDB('local').oplog.rs.find().sort({$natural: -1}).limit(1).next(); + }; + + var primaryDB = rst.getPrimary().getDB('test'); + var op = getLatestOp(); + + // Enable profiling on the primary + assert.commandWorked(primaryDB.runCommand({profile: 2})); + assert.eq(op, getLatestOp(), "oplog entry created when profile was enabled"); + assert.writeOK(primaryDB.foo.insert({})); + op = getLatestOp(); + assert.commandWorked(primaryDB.runCommand({profile: 0})); + assert.eq(op, getLatestOp(), "oplog entry created when profile was disabled"); + + // dropCollection + assert(primaryDB.system.profile.drop()); + assert.eq(op, getLatestOp(), "oplog entry created when system.profile was dropped"); + + assert.commandWorked(primaryDB.createCollection("system.profile", {capped: true, size: 1000})); + assert.eq(op, getLatestOp(), "oplog entry created when system.profile was created"); + assert.commandWorked(primaryDB.runCommand({profile: 2})); + assert.writeOK(primaryDB.foo.insert({})); + op = getLatestOp(); + assert.commandWorked(primaryDB.runCommand({profile: 0})); + + // emptycapped the collection + assert.commandWorked(primaryDB.runCommand({emptycapped: "system.profile"})); + assert.eq(op, getLatestOp(), + "oplog entry created when system.profile was emptied via emptycapped"); + assert(primaryDB.system.profile.drop()); + + // convertToCapped + assert.commandWorked(primaryDB.createCollection("system.profile")); + assert.commandWorked(primaryDB.runCommand({convertToCapped: "system.profile", size: 1000})); + assert.eq(op, getLatestOp(), "oplog entry created when system.profile was convertedToCapped"); + assert(primaryDB.system.profile.drop()); +})(); diff --git a/src/mongo/db/op_observer.cpp b/src/mongo/db/op_observer.cpp index 9d655fabdf7..978f0677dfa 100644 --- a/src/mongo/db/op_observer.cpp +++ b/src/mongo/db/op_observer.cpp @@ -111,7 +111,10 @@ namespace mongo { b.appendElements(options.toBSON()); BSONObj cmdObj = b.obj(); - repl::_logOp(txn, "c", dbName.c_str(), cmdObj, nullptr, false); + if (!collectionName.isSystemDotProfile()) { + // do not replicate system.profile modifications + repl::_logOp(txn, "c", dbName.c_str(), cmdObj, nullptr, false); + } getGlobalAuthorizationManager()->logOp(txn, "c", dbName.c_str(), cmdObj, nullptr); logOpForDbHash(txn, dbName.c_str()); @@ -120,7 +123,13 @@ namespace mongo { void OpObserver::onCollMod(OperationContext* txn, const std::string& dbName, const BSONObj& collModCmd) { - repl::_logOp(txn, "c", dbName.c_str(), collModCmd, nullptr, false); + BSONElement first = collModCmd.firstElement(); + std::string coll = first.valuestr(); + + if (!NamespaceString(NamespaceString(dbName).db(), coll).isSystemDotProfile()) { + // do not replicate system.profile modifications + repl::_logOp(txn, "c", dbName.c_str(), collModCmd, nullptr, false); + } getGlobalAuthorizationManager()->logOp(txn, "c", dbName.c_str(), collModCmd, nullptr); logOpForDbHash(txn, dbName.c_str()); @@ -141,7 +150,10 @@ namespace mongo { std::string dbName = collectionName.db().toString() + ".$cmd"; BSONObj cmdObj = BSON("drop" << collectionName.coll().toString()); - repl::_logOp(txn, "c", dbName.c_str(), cmdObj, nullptr, false); + if (!collectionName.isSystemDotProfile()) { + // do not replicate system.profile modifications + repl::_logOp(txn, "c", dbName.c_str(), cmdObj, nullptr, false); + } getGlobalAuthorizationManager()->logOp(txn, "c", dbName.c_str(), cmdObj, nullptr); logOpForDbHash(txn, dbName.c_str()); @@ -188,7 +200,10 @@ namespace mongo { std::string dbName = collectionName.db().toString() + ".$cmd"; BSONObj cmdObj = BSON("convertToCapped" << collectionName.coll() << "size" << size); - repl::_logOp(txn, "c", dbName.c_str(), cmdObj, nullptr, false); + if (!collectionName.isSystemDotProfile()) { + // do not replicate system.profile modifications + repl::_logOp(txn, "c", dbName.c_str(), cmdObj, nullptr, false); + } getGlobalAuthorizationManager()->logOp(txn, "c", dbName.c_str(), cmdObj, nullptr); logOpForDbHash(txn, dbName.c_str()); @@ -198,7 +213,10 @@ namespace mongo { std::string dbName = collectionName.db().toString() + ".$cmd"; BSONObj cmdObj = BSON("emptycapped" << collectionName.coll()); - repl::_logOp(txn, "c", dbName.c_str(), cmdObj, nullptr, false); + if (!collectionName.isSystemDotProfile()) { + // do not replicate system.profile modifications + repl::_logOp(txn, "c", dbName.c_str(), cmdObj, nullptr, false); + } getGlobalAuthorizationManager()->logOp(txn, "c", dbName.c_str(), cmdObj, nullptr); logOpForDbHash(txn, dbName.c_str()); |