summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatt dannenberg <matt.dannenberg@10gen.com>2015-06-16 08:06:18 -0400
committermatt dannenberg <matt.dannenberg@10gen.com>2015-06-17 13:22:36 -0400
commit7523229c8dda361a10a42e622fc04441f5011fb6 (patch)
tree9a28af37c9bc501f3c393d3b2a3cd8b8bdabecf2
parentbdf6a4b8af528241818ce03ce2483ac3c0c2aeff (diff)
downloadmongo-7523229c8dda361a10a42e622fc04441f5011fb6.tar.gz
SERVER-18962 do not replicate metadata operations pertaining to system.profile
-rw-r--r--jstests/replsets/system_profile.js48
-rw-r--r--src/mongo/db/op_observer.cpp28
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());