summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jstests/libs/feature_compatibility_version.js29
-rw-r--r--jstests/multiVersion/remove_feature_compatibility_version.js18
-rw-r--r--jstests/multiVersion/set_feature_compatibility_version.js26
-rw-r--r--jstests/noPassthrough/feature_compatibility_version.js30
-rw-r--r--src/mongo/db/commands/rename_collection_cmd.cpp7
-rw-r--r--src/mongo/db/namespace_string.h3
-rw-r--r--src/mongo/db/op_observer_impl.cpp7
-rw-r--r--src/mongo/db/repl/sync_tail_test.cpp43
8 files changed, 65 insertions, 98 deletions
diff --git a/jstests/libs/feature_compatibility_version.js b/jstests/libs/feature_compatibility_version.js
index 116706eaf27..81ac0956ae4 100644
--- a/jstests/libs/feature_compatibility_version.js
+++ b/jstests/libs/feature_compatibility_version.js
@@ -30,4 +30,31 @@ function checkFCV34(adminDB, version) {
let doc = adminDB.system.version.findOne({_id: "featureCompatibilityVersion"});
assert.eq(doc.version, version, tojson(doc));
-} \ No newline at end of file
+}
+
+/**
+ * Since SERVER-29453 disallows us to remove the FCV document in 3.6, we need to
+ * do this hack to remove it. Notice this is only for 3.6. For 3.4, we can
+ * simply remove the FCV document.
+ */
+function removeFCVDocument(adminDB) {
+ let res = adminDB.runCommand({listCollections: 1, filter: {name: "system.version"}});
+ assert.commandWorked(res, "failed to list collections");
+ let originalUUID = res.cursor.firstBatch[0].info.uuid;
+ let newUUID = UUID();
+
+ // Create new collection with no FCV document, and then delete the
+ // original collection.
+ let createNewAdminSystemVersionCollection =
+ {op: "c", ns: "admin.$cmd", ui: newUUID, o: {create: "system.version"}};
+ let dropOriginalAdminSystemVersionCollection =
+ {op: "c", ns: "admin.$cmd", ui: originalUUID, o: {drop: "admin.tmp_system_version"}};
+ assert.commandWorked(adminDB.runCommand({
+ applyOps:
+ [createNewAdminSystemVersionCollection, dropOriginalAdminSystemVersionCollection]
+ }));
+
+ res = adminDB.runCommand({listCollections: 1, filter: {name: "system.version"}});
+ assert.commandWorked(res, "failed to list collections");
+ assert.eq(newUUID, res.cursor.firstBatch[0].info.uuid);
+}
diff --git a/jstests/multiVersion/remove_feature_compatibility_version.js b/jstests/multiVersion/remove_feature_compatibility_version.js
new file mode 100644
index 00000000000..6e1448d5f5e
--- /dev/null
+++ b/jstests/multiVersion/remove_feature_compatibility_version.js
@@ -0,0 +1,18 @@
+/**
+ * This test is for SERVER-29453: Renaming the admin.system.version collection
+ * or removing the FCV document should not be allowed.
+ */
+(function() {
+ 'use strict';
+
+ let standalone = MongoRunner.runMongod();
+ assert.neq(null, standalone, 'mongod was unable to start up');
+ let adminDB = standalone.getDB('admin');
+
+ // Renaming the collection or deleting the document should fail.
+ assert.commandFailedWithCode(
+ adminDB.runCommand(
+ {renameCollection: 'admin.system.version', to: 'admin.dummy.collection'}),
+ ErrorCodes.IllegalOperation);
+ assert.writeErrorWithCode(adminDB.system.version.remove({}), 40670);
+})();
diff --git a/jstests/multiVersion/set_feature_compatibility_version.js b/jstests/multiVersion/set_feature_compatibility_version.js
index 83c88ec77f5..abf6043546d 100644
--- a/jstests/multiVersion/set_feature_compatibility_version.js
+++ b/jstests/multiVersion/set_feature_compatibility_version.js
@@ -80,13 +80,15 @@ TestData.skipCheckingUUIDsConsistentAcrossCluster = true;
adminDB.system.version.findOne({_id: "featureCompatibilityVersion"}).version,
"3.6",
"expected 3.6 mongod with no data files to start up with featureCompatibilityVersion 3.6");
+ removeFCVDocument(adminDB);
} else {
assert.eq(
adminDB.system.version.findOne({_id: "featureCompatibilityVersion"}).version,
"3.4",
"expected 3.4 mongod with no data files to start up with featureCompatibilityVersion 3.4");
+ assert.writeOK(adminDB.system.version.remove({_id: "featureCompatibilityVersion"}));
}
- assert.writeOK(adminDB.system.version.remove({_id: "featureCompatibilityVersion"}));
+
MongoRunner.stopMongod(conn);
return conn;
};
@@ -376,28 +378,6 @@ TestData.skipCheckingUUIDsConsistentAcrossCluster = true;
0);
rst.stopSet();
- // A mixed 3.4/3.6 replica set without a featureCompatibilityVersion document unfortunately
- // reports mixed 3.2/3.4 featureCompatibilityVersion.
- rst = new ReplSetTest({nodes: [{binVersion: downgrade}, {binVersion: latest}]});
- rstConns = rst.startSet();
- replSetConfig = rst.getReplSetConfig();
- replSetConfig.members[1].priority = 0;
- replSetConfig.members[1].votes = 0;
- rst.initiate(replSetConfig);
-
- primaryAdminDB = rst.getPrimary().getDB("admin");
- secondaryAdminDB = rst.getSecondary().getDB("admin");
- assert.writeOK(primaryAdminDB.system.version.remove({_id: "featureCompatibilityVersion"},
- {writeConcern: {w: 2}}));
- res = primaryAdminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1});
- assert.commandWorked(res);
- assert.eq(res.featureCompatibilityVersion, "3.2");
- res = secondaryAdminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1});
- assert.commandWorked(res);
- assert.eq(res.featureCompatibilityVersion.version, "3.4", tojson(res));
- assert.eq(res.featureCompatibilityVersion.targetVersion, null, tojson(res));
- rst.stopSet();
-
// Test idempotency for setFeatureCompatibilityVersion.
rst = new ReplSetTest({nodes: 2, nodeOpts: {binVersion: latest}});
rst.startSet();
diff --git a/jstests/noPassthrough/feature_compatibility_version.js b/jstests/noPassthrough/feature_compatibility_version.js
index de37a2a29a2..016c5d12e08 100644
--- a/jstests/noPassthrough/feature_compatibility_version.js
+++ b/jstests/noPassthrough/feature_compatibility_version.js
@@ -12,11 +12,6 @@
*/
let checkFCVDocumentMissing = function(adminDB) {
assert.eq(null, adminDB.system.version.findOne({_id: "featureCompatibilityVersion"}));
-
- let res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1});
- assert.commandWorked(res);
- assert.eq("3.4", res.featureCompatibilityVersion.version, tojson(res));
- assert.eq(null, res.featureCompatibilityVersion.targetVersion, tojson(res));
};
const conn = MongoRunner.runMongod({});
@@ -65,7 +60,7 @@
// Deleting the featureCompatibilityVersion document changes the featureCompatibilityVersion
// server parameter to 3.4.
- assert.writeOK(adminDB.system.version.remove({_id: "featureCompatibilityVersion"}));
+ removeFCVDocument(adminDB);
checkFCVDocumentMissing(adminDB);
// Inserting a featureCompatibilityVersion document with an invalid version fails.
@@ -92,29 +87,6 @@
ErrorCodes.BadValue);
checkFCVDocumentMissing(adminDB);
- // Inserting the featureCompatibilityVersion document changes the featureCompatibilityVersion
- // server parameter.
- assert.writeOK(
- adminDB.system.version.insert({_id: "featureCompatibilityVersion", version: "3.4"}));
- checkFCV(adminDB, "3.4");
-
- assert.writeOK(adminDB.system.version.remove({_id: "featureCompatibilityVersion"}));
- checkFCVDocumentMissing(adminDB);
-
- assert.writeOK(adminDB.system.version.insert(
- {_id: "featureCompatibilityVersion", version: "3.4", targetVersion: "3.6"}));
- checkFCV(adminDB, "3.4", "3.6");
-
- assert.writeOK(adminDB.system.version.remove({_id: "featureCompatibilityVersion"}));
- checkFCVDocumentMissing(adminDB);
-
- assert.writeOK(adminDB.system.version.insert(
- {_id: "featureCompatibilityVersion", version: "3.4", targetVersion: "3.4"}));
- checkFCV(adminDB, "3.4", "3.4");
-
- assert.writeOK(adminDB.system.version.remove({_id: "featureCompatibilityVersion"}));
- checkFCVDocumentMissing(adminDB);
-
assert.writeOK(
adminDB.system.version.insert({_id: "featureCompatibilityVersion", version: "3.6"}));
checkFCV(adminDB, "3.6");
diff --git a/src/mongo/db/commands/rename_collection_cmd.cpp b/src/mongo/db/commands/rename_collection_cmd.cpp
index 569907eaab2..6385dcc5d0f 100644
--- a/src/mongo/db/commands/rename_collection_cmd.cpp
+++ b/src/mongo/db/commands/rename_collection_cmd.cpp
@@ -144,6 +144,13 @@ public:
return false;
}
+ if (source.isAdminDotSystemDotVersion()) {
+ appendCommandStatus(result,
+ Status(ErrorCodes::IllegalOperation,
+ "renaming admin.system.version is not allowed"));
+ return false;
+ }
+
RenameCollectionOptions options;
options.dropTarget = cmdObj["dropTarget"].trueValue();
options.stayTemp = cmdObj["stayTemp"].trueValue();
diff --git a/src/mongo/db/namespace_string.h b/src/mongo/db/namespace_string.h
index f110489916e..07240fa9f0a 100644
--- a/src/mongo/db/namespace_string.h
+++ b/src/mongo/db/namespace_string.h
@@ -192,6 +192,9 @@ public:
bool isSystemDotViews() const {
return coll() == kSystemDotViewsCollectionName;
}
+ bool isAdminDotSystemDotVersion() const {
+ return ((db() == "admin") && (coll() == "system.version"));
+ }
bool isConfigDB() const {
return db() == "config";
}
diff --git a/src/mongo/db/op_observer_impl.cpp b/src/mongo/db/op_observer_impl.cpp
index 6da9b7f9599..cdc1dbc4756 100644
--- a/src/mongo/db/op_observer_impl.cpp
+++ b/src/mongo/db/op_observer_impl.cpp
@@ -437,8 +437,11 @@ void OpObserverImpl::onDelete(OperationContext* opCtx,
Scope::storedFuncMod(opCtx);
} else if (nss.coll() == DurableViewCatalog::viewsCollectionName()) {
DurableViewCatalog::onExternalChange(opCtx, nss);
- } else if (nss.ns() == FeatureCompatibilityVersion::kCollection) {
- FeatureCompatibilityVersion::onDelete(opCtx, deleteState.documentKey);
+ } else if (nss.isAdminDotSystemDotVersion()) {
+ auto _id = deleteState.documentKey["_id"];
+ if (_id.type() == BSONType::String &&
+ _id.String() == FeatureCompatibilityVersion::kParameterName)
+ uasserted(40670, "removing FeatureCompatibilityVersion document is not allowed");
} else if (nss == NamespaceString::kSessionTransactionsTableNamespace &&
!opTime.writeOpTime.isNull()) {
SessionCatalog::get(opCtx)->invalidateSessions(opCtx, deleteState.documentKey);
diff --git a/src/mongo/db/repl/sync_tail_test.cpp b/src/mongo/db/repl/sync_tail_test.cpp
index e1c83e5e89f..6f7537ee68f 100644
--- a/src/mongo/db/repl/sync_tail_test.cpp
+++ b/src/mongo/db/repl/sync_tail_test.cpp
@@ -1664,29 +1664,6 @@ TEST_F(SyncTailTest, FailOnDropFCVCollectionInRecovering) {
ASSERT_EQUALS(runOpSteadyState(op), ErrorCodes::OplogOperationUnsupported);
}
-TEST_F(SyncTailTest, FailOnDeleteFCVDocumentInRecovering) {
- auto fcvNS = NamespaceString(FeatureCompatibilityVersion::kCollection);
- CollectionOptions options;
- options.uuid = UUID::gen();
- ::mongo::repl::createCollection(_opCtx.get(), fcvNS, options);
-
- // Insert the fCV document.
- ASSERT_OK(
- ReplicationCoordinator::get(_opCtx.get())->setFollowerMode(MemberState::RS_SECONDARY));
- auto insertCmd = BSON("_id" << FeatureCompatibilityVersion::kParameterName
- << FeatureCompatibilityVersion::kVersionField
- << FeatureCompatibilityVersionCommandParser::kVersion36);
- auto insertOp = makeInsertDocumentOplogEntry(nextOpTime(), fcvNS, insertCmd);
- ASSERT_OK(runOpSteadyState(insertOp));
-
- ASSERT_OK(
- ReplicationCoordinator::get(_opCtx.get())->setFollowerMode(MemberState::RS_RECOVERING));
-
- auto cmd = BSON("_id" << FeatureCompatibilityVersion::kParameterName);
- auto op = makeDeleteDocumentOplogEntry(nextOpTime(), fcvNS, cmd);
- ASSERT_EQUALS(runOpSteadyState(op), ErrorCodes::OplogOperationUnsupported);
-}
-
TEST_F(SyncTailTest, SuccessOnUpdateFCV34TargetVersionUnsetDocumentInRecovering) {
auto fcvNS = NamespaceString(FeatureCompatibilityVersion::kCollection);
::mongo::repl::createCollection(_opCtx.get(), fcvNS, CollectionOptions());
@@ -1732,26 +1709,6 @@ TEST_F(SyncTailTest, SuccessOnDropFCVCollectionInSecondary) {
ASSERT_OK(runOpSteadyState(op));
}
-TEST_F(SyncTailTest, SuccessOnDeleteFCVDocumentInSecondary) {
- auto fcvNS = NamespaceString(FeatureCompatibilityVersion::kCollection);
- CollectionOptions options;
- options.uuid = UUID::gen();
- ::mongo::repl::createCollection(_opCtx.get(), fcvNS, options);
- ASSERT_OK(
- ReplicationCoordinator::get(_opCtx.get())->setFollowerMode(MemberState::RS_SECONDARY));
-
- // Insert the fCV document.
- auto insertCmd = BSON("_id" << FeatureCompatibilityVersion::kParameterName
- << FeatureCompatibilityVersion::kVersionField
- << FeatureCompatibilityVersionCommandParser::kVersion36);
- auto insertOp = makeInsertDocumentOplogEntry(nextOpTime(), fcvNS, insertCmd);
- ASSERT_OK(runOpSteadyState(insertOp));
-
- auto cmd = BSON("_id" << FeatureCompatibilityVersion::kParameterName);
- auto op = makeDeleteDocumentOplogEntry(nextOpTime(), fcvNS, cmd);
- ASSERT_OK(runOpSteadyState(op));
-}
-
TEST_F(SyncTailTest, SuccessOnUpdateFCV34TargetVersion34DocumentInSecondary) {
auto fcvNS = NamespaceString(FeatureCompatibilityVersion::kCollection);
::mongo::repl::createCollection(_opCtx.get(), fcvNS, CollectionOptions());