summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Grebennicov <denis.grebennicov@mongodb.com>2023-02-17 11:55:00 +0100
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2023-02-17 14:08:55 +0000
commit10fd84b6850ef672ff6ed367ca9292ad8db262d2 (patch)
treef442538321821d6b684ad6e8760b6462d1a07767
parent78ba288ddc56067bdfec2479284a61683984c14f (diff)
downloadmongo-r6.2.1-rc1.tar.gz
SERVER-73833 Make the server to ignore and automatically remove unsupported 'recordPreImages' collection optionr6.2.1-rc1r6.2.1
-rw-r--r--jstests/multiVersion/targetedTestsLastLtsFeatures/recordPreImages_option_upgrade.js69
-rw-r--r--src/mongo/db/catalog/collection_options.cpp4
-rw-r--r--src/mongo/db/catalog/collection_options.h6
-rw-r--r--src/mongo/db/commands/set_feature_compatibility_version_command.cpp32
4 files changed, 108 insertions, 3 deletions
diff --git a/jstests/multiVersion/targetedTestsLastLtsFeatures/recordPreImages_option_upgrade.js b/jstests/multiVersion/targetedTestsLastLtsFeatures/recordPreImages_option_upgrade.js
new file mode 100644
index 00000000000..6f86dcb202c
--- /dev/null
+++ b/jstests/multiVersion/targetedTestsLastLtsFeatures/recordPreImages_option_upgrade.js
@@ -0,0 +1,69 @@
+/**
+ * Verifies that the server ignores collection option "recordPreImages" on binary upgrade from the
+ * last LTS version to the current, as well as removes the option from collection attributes on
+ * FCV upgrade.
+ */
+(function() {
+"use strict";
+load('jstests/multiVersion/libs/multi_rs.js');
+
+const lastLTSVersion = "last-lts";
+const latestVersion = "latest";
+
+// Setup a two-node replica set with last LTS binaries, so it is possible to create a collection
+// with "recordPreImages" option.
+const rst = new ReplSetTest(
+ {name: jsTestName(), nodes: [{binVersion: lastLTSVersion}, {binVersion: lastLTSVersion}]});
+rst.startSet();
+rst.initiate();
+const testDB = rst.getPrimary().getDB("test");
+const primaryNode = rst.getPrimary();
+const secondaryNode = rst.getSecondary();
+
+// Create the collection.
+const collectionName = "coll";
+assert.commandWorked(testDB.createCollection(collectionName, {recordPreImages: true}));
+let coll = testDB[collectionName];
+
+// Insert a test document which will be updated to trigger recording of change stream pre-images.
+assert.commandWorked(coll.insert({_id: 1, a: 1}));
+assert.commandWorked(coll.updateOne({_id: 1}, {$inc: {a: 1}}));
+rst.awaitReplication();
+
+// Upgrade the binary of the secondary node to the current version to setup a mixed binary cluster.
+rst.upgradeMembers([secondaryNode], {binVersion: latestVersion});
+
+// Make sure the primary node did not change.
+rst.stepUp(primaryNode);
+
+// Verify that recording of change stream pre-images succeeds.
+assert.commandWorked(coll.updateOne({_id: 1}, {$inc: {a: 1}}));
+rst.awaitReplication();
+
+// Finally upgrade the binary of the primary node to the current version.
+rst.upgradePrimary(rst.getPrimary(), {binVersion: latestVersion});
+
+// Update a document on the collection with inactive "recordPreImages" collection option.
+coll = rst.getPrimary().getDB("test")[collectionName];
+assert.commandWorked(coll.updateOne({_id: 1}, {$inc: {a: 1}}));
+rst.awaitReplication();
+
+// Upgrade the FCV to the latest to trigger removal of "recordPreImages" collection option from
+// persistent catalog entries.
+assert.commandWorked(rst.getPrimary().adminCommand({setFeatureCompatibilityVersion: latestFCV}));
+
+// To check the collection options, downgrade FCV to later replace the binary of the server with
+// the last LTS binary version.
+assert.commandWorked(rst.getPrimary().adminCommand({setFeatureCompatibilityVersion: lastLTSFCV}));
+rst.upgradeSet({binVersion: lastLTSVersion});
+
+// Verify that collection option "recordPreImages" was removed.
+const result =
+ assert.commandWorked(rst.getPrimary().getDB("test").runCommand({listCollections: 1}));
+assert.eq(result.cursor.firstBatch[0].name, collectionName);
+assert.docEq(
+ {},
+ result.cursor.firstBatch[0].options,
+ `Collection option "recordPreImages" was not removed. Got response: ${tojson(result)}`);
+rst.stopSet();
+})(); \ No newline at end of file
diff --git a/src/mongo/db/catalog/collection_options.cpp b/src/mongo/db/catalog/collection_options.cpp
index 4e235d62a71..297c4d45bef 100644
--- a/src/mongo/db/catalog/collection_options.cpp
+++ b/src/mongo/db/catalog/collection_options.cpp
@@ -174,6 +174,10 @@ StatusWith<CollectionOptions> CollectionOptions::parse(const BSONObj& options, P
} else if (fieldName == "flags") {
// Ignoring this field as it is deprecated.
continue;
+ } else if (fieldName == "recordPreImages") {
+ // Ignoring this field as it is not supported.
+ collectionOptions.recordPreImagesOptionUsed = true;
+ continue;
} else if (fieldName == "temp") {
collectionOptions.temp = e.trueValue();
} else if (fieldName == "changeStreamPreAndPostImages") {
diff --git a/src/mongo/db/catalog/collection_options.h b/src/mongo/db/catalog/collection_options.h
index 2e1d06aa190..f5dc1dd0c55 100644
--- a/src/mongo/db/catalog/collection_options.h
+++ b/src/mongo/db/catalog/collection_options.h
@@ -124,6 +124,12 @@ struct CollectionOptions {
bool temp = false;
+ // Indicates whether "recordPreImages" collection option was used in the collection definition.
+ // This needs to be remembered to make it possible to efficiently remove the option upon FCV
+ // upgrade. Otherwise, this option is not supported.
+ // TODO SERVER-74036: Remove once FCV 7.0 becomes last-LTS.
+ bool recordPreImagesOptionUsed{false};
+
// Change stream options define whether or not to store the pre-images of the documents affected
// by update and delete operations in a dedicated collection, that will be used for reading data
// via changeStreams.
diff --git a/src/mongo/db/commands/set_feature_compatibility_version_command.cpp b/src/mongo/db/commands/set_feature_compatibility_version_command.cpp
index e7789ea0eea..58c5121c2dd 100644
--- a/src/mongo/db/commands/set_feature_compatibility_version_command.cpp
+++ b/src/mongo/db/commands/set_feature_compatibility_version_command.cpp
@@ -499,10 +499,9 @@ private:
if (serverGlobalParams.clusterRole == ClusterRole::ConfigServer) {
_cleanupConfigVersionOnUpgrade(opCtx, requestedVersion);
_createSchemaOnConfigSettings(opCtx, requestedVersion);
- } else if (serverGlobalParams.clusterRole == ClusterRole::ShardServer) {
- } else {
- return;
}
+
+ _removeRecordPreImagesCollectionOption(opCtx);
}
// TODO SERVER-68889 remove once 7.0 becomes last LTS
@@ -592,6 +591,33 @@ private:
}
}
+ // Removes collection option "recordPreImages" from all collection definitions.
+ // TODO SERVER-74036: Remove once FCV 7.0 becomes last-LTS.
+ void _removeRecordPreImagesCollectionOption(OperationContext* opCtx) {
+ for (const auto& dbName : DatabaseHolder::get(opCtx)->getNames()) {
+ Lock::DBLock dbLock(opCtx, dbName, MODE_IX);
+ catalog::forEachCollectionFromDb(
+ opCtx,
+ dbName,
+ MODE_X,
+ [&](const CollectionPtr& collection) {
+ // To remove collection option "recordPreImages" from persistent storage, issue
+ // the "collMod" command with none of the parameters set.
+ BSONObjBuilder responseBuilder;
+ uassertStatusOK(processCollModCommand(
+ opCtx, collection->ns(), CollMod{collection->ns()}, &responseBuilder));
+ LOGV2(7383300,
+ "Removed 'recordPreImages' collection option",
+ "ns"_attr = collection->ns(),
+ "collModResponse"_attr = responseBuilder.obj());
+ return true;
+ },
+ [&](const CollectionPtr& collection) {
+ return collection->getCollectionOptions().recordPreImagesOptionUsed;
+ });
+ }
+ }
+
// _runUpgrade performs all the upgrade specific code for setFCV. Any new feature specific
// upgrade code should be placed in the _runUpgrade helper functions:
// * _prepareForUpgrade: for any upgrade actions that should be done before taking the FCV full