diff options
author | Tess Avitabile <tess.avitabile@mongodb.com> | 2017-02-28 16:48:14 -0500 |
---|---|---|
committer | Tess Avitabile <tess.avitabile@mongodb.com> | 2017-03-02 17:41:51 -0500 |
commit | 3cbd42ec420605aac92cdf6817ea9ec1e9410ebd (patch) | |
tree | b99aec42398f3e7e929900dfdda33ac0030a9e64 | |
parent | 3494a01655326a299d60f06432d7cc1bc11aecd6 (diff) | |
download | mongo-3cbd42ec420605aac92cdf6817ea9ec1e9410ebd.tar.gz |
SERVER-27972 Add a featureCompatibilityVersion op observer for database/collection drop
4 files changed, 102 insertions, 0 deletions
diff --git a/jstests/noPassthrough/feature_compatibility_version.js b/jstests/noPassthrough/feature_compatibility_version.js new file mode 100644 index 00000000000..d9c1368b15b --- /dev/null +++ b/jstests/noPassthrough/feature_compatibility_version.js @@ -0,0 +1,80 @@ +// Tests that manipulating the featureCompatibilityVersion document in admin.system.version changes +// the value of the featureCompatibilityVersion server parameter. + +(function() { + "use strict"; + + const conn = MongoRunner.runMongod({}); + assert.neq(null, conn, "mongod was unable to start up"); + + let adminDB = conn.getDB("admin"); + + // Initially the featureCompatibilityVersion is 3.4. + let res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); + assert.commandWorked(res); + assert.eq("3.4", res.featureCompatibilityVersion); + + // Updating the featureCompatibilityVersion document changes the featureCompatibilityVersion + // server parameter. + assert.writeOK(adminDB.system.version.update({_id: "featureCompatibilityVersion"}, + {$set: {version: "3.2"}})); + res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); + assert.commandWorked(res); + assert.eq("3.2", res.featureCompatibilityVersion); + + assert.writeOK(adminDB.system.version.update({_id: "featureCompatibilityVersion"}, + {$set: {version: "3.4"}})); + res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); + assert.commandWorked(res); + assert.eq("3.4", res.featureCompatibilityVersion); + + // Updating the featureCompatibilityVersion document with an invalid version fails. + assert.writeErrorWithCode(adminDB.system.version.update({_id: "featureCompatibilityVersion"}, + {$set: {version: "3.6"}}), + ErrorCodes.BadValue); + res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); + assert.commandWorked(res); + assert.eq("3.4", res.featureCompatibilityVersion); + + // Deleting the featureCompatibilityVersion document changes the featureCompatibilityVersion + // server parameter to 3.2. + assert.writeOK(adminDB.system.version.remove({_id: "featureCompatibilityVersion"})); + res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); + assert.commandWorked(res); + assert.eq("3.2", res.featureCompatibilityVersion); + + // Inserting a featureCompatibilityVersion document with an invalid version fails. + assert.writeErrorWithCode( + adminDB.system.version.insert({_id: "featureCompatibilityVersion", version: "3.6"}), + ErrorCodes.BadValue); + res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); + assert.commandWorked(res); + assert.eq("3.2", res.featureCompatibilityVersion); + + // Inserting the featureCompatibilityVersion document changes the featureCompatibilityVersion + // server parameter. + assert.writeOK( + adminDB.system.version.insert({_id: "featureCompatibilityVersion", version: "3.2"})); + res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); + assert.commandWorked(res); + assert.eq("3.2", res.featureCompatibilityVersion); + + assert.writeOK(adminDB.system.version.remove({_id: "featureCompatibilityVersion"})); + res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); + assert.commandWorked(res); + assert.eq("3.2", res.featureCompatibilityVersion); + + assert.writeOK( + adminDB.system.version.insert({_id: "featureCompatibilityVersion", version: "3.4"})); + res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); + assert.commandWorked(res); + assert.eq("3.4", res.featureCompatibilityVersion); + + // Dropping the admin database changes the featureCompatibilityVersion server parameter to 3.2. + adminDB.dropDatabase(); + res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); + assert.commandWorked(res); + assert.eq("3.2", res.featureCompatibilityVersion); + + MongoRunner.stopMongod(conn); +}()); diff --git a/src/mongo/db/commands/feature_compatibility_version.cpp b/src/mongo/db/commands/feature_compatibility_version.cpp index 73988bef0c7..448e134de22 100644 --- a/src/mongo/db/commands/feature_compatibility_version.cpp +++ b/src/mongo/db/commands/feature_compatibility_version.cpp @@ -57,6 +57,7 @@ using repl::UnreplicatedWritesBlock; constexpr StringData FeatureCompatibilityVersion::k32IncompatibleIndexName; constexpr StringData FeatureCompatibilityVersion::kCollection; constexpr StringData FeatureCompatibilityVersion::kCommandName; +constexpr StringData FeatureCompatibilityVersion::kDatabase; constexpr StringData FeatureCompatibilityVersion::kParameterName; constexpr StringData FeatureCompatibilityVersion::kVersionField; @@ -352,6 +353,13 @@ void FeatureCompatibilityVersion::onDelete(const BSONObj& doc) { ServerGlobalParams::FeatureCompatibility::Version::k32); } +void FeatureCompatibilityVersion::onDropCollection() { + log() << "setting featureCompatibilityVersion to " + << FeatureCompatibilityVersionCommandParser::kVersion32; + serverGlobalParams.featureCompatibility.version.store( + ServerGlobalParams::FeatureCompatibility::Version::k32); +} + /** * Read-only server parameter for featureCompatibilityVersion. */ diff --git a/src/mongo/db/commands/feature_compatibility_version.h b/src/mongo/db/commands/feature_compatibility_version.h index 46fa8390bb3..4bcb4b56e55 100644 --- a/src/mongo/db/commands/feature_compatibility_version.h +++ b/src/mongo/db/commands/feature_compatibility_version.h @@ -50,6 +50,7 @@ public: static constexpr StringData k32IncompatibleIndexName = "incompatible_with_version_32"_sd; static constexpr StringData kCollection = "admin.system.version"_sd; static constexpr StringData kCommandName = "setFeatureCompatibilityVersion"_sd; + static constexpr StringData kDatabase = "admin"_sd; static constexpr StringData kParameterName = "featureCompatibilityVersion"_sd; static constexpr StringData kVersionField = "version"_sd; @@ -85,6 +86,11 @@ public: * featureCompatibilityVersion document, resets the server parameter to its default value (3.2). */ static void onDelete(const BSONObj& doc); + + /** + * Resets the server parameter to its default value (3.2). + */ + static void onDropCollection(); }; } // namespace mongo diff --git a/src/mongo/db/op_observer_impl.cpp b/src/mongo/db/op_observer_impl.cpp index e8b796daac2..00560851a7a 100644 --- a/src/mongo/db/op_observer_impl.cpp +++ b/src/mongo/db/op_observer_impl.cpp @@ -220,6 +220,10 @@ void OpObserverImpl::onDropDatabase(OperationContext* txn, const std::string& db repl::logOp(txn, "c", dbName.c_str(), cmdObj, nullptr, false); + if (NamespaceString(dbName).db() == FeatureCompatibilityVersion::kDatabase) { + FeatureCompatibilityVersion::onDropCollection(); + } + getGlobalAuthorizationManager()->logOp(txn, "c", dbName.c_str(), cmdObj, nullptr); logOpForDbHash(txn, dbName.c_str()); } @@ -238,6 +242,10 @@ void OpObserverImpl::onDropCollection(OperationContext* txn, DurableViewCatalog::onExternalChange(txn, collectionName); } + if (collectionName.ns() == FeatureCompatibilityVersion::kCollection) { + FeatureCompatibilityVersion::onDropCollection(); + } + getGlobalAuthorizationManager()->logOp(txn, "c", dbName.c_str(), cmdObj, nullptr); auto css = CollectionShardingState::get(txn, collectionName); |