summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMindaugas Malinauskas <mindaugas.malinauskas@mongodb.com>2021-10-19 16:39:13 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-10-19 17:03:18 +0000
commit480da702d82f458a9d954092a42f56c2d064b6f4 (patch)
tree5243d6d3027f6d7cc0edce8362e6398736cfb377
parentfbbcca323c3099398540c7f44a4b6d73589fba6d (diff)
downloadmongo-480da702d82f458a9d954092a42f56c2d064b6f4.tar.gz
SERVER-58825 Make pre-images collection clustered
-rw-r--r--jstests/change_streams/lookup_pit_pre_and_post_image.js8
-rw-r--r--jstests/change_streams/write_pit_preimage.js2
-rw-r--r--jstests/multiVersion/change_streams_pre_and_post_images_upgrade_downgrade.js59
-rw-r--r--jstests/noPassthrough/change_streams_pre_and_post_images_in_create_and_collmod.js49
-rw-r--r--src/mongo/db/catalog/create_collection.cpp15
-rw-r--r--src/mongo/db/catalog/create_collection.h4
6 files changed, 79 insertions, 58 deletions
diff --git a/jstests/change_streams/lookup_pit_pre_and_post_image.js b/jstests/change_streams/lookup_pit_pre_and_post_image.js
index b10ed83a125..69153720d61 100644
--- a/jstests/change_streams/lookup_pit_pre_and_post_image.js
+++ b/jstests/change_streams/lookup_pit_pre_and_post_image.js
@@ -14,7 +14,11 @@ load("jstests/libs/change_stream_util.js"); // For isChangeStreamPreAndPo
const testDB = db.getSiblingDB(jsTestName());
const collName = "test";
-if (!isChangeStreamPreAndPostImagesEnabled(db)) {
+const clusteredIndexesEnabled =
+ assert.commandWorked(testDB.adminCommand({getParameter: 1, featureFlagClusteredIndexes: 1}))
+ .featureFlagClusteredIndexes.value;
+
+if (!(isChangeStreamPreAndPostImagesEnabled(db) && clusteredIndexesEnabled)) {
const coll = assertDropAndRecreateCollection(testDB, collName);
// If feature flag is off, creating changeStream with new fullDocument arguments should throw.
@@ -23,7 +27,7 @@ if (!isChangeStreamPreAndPostImagesEnabled(db)) {
assert.throwsWithCode(() => coll.watch([], {fullDocument: 'required'}), ErrorCodes.BadValue);
jsTestLog(
- 'Skipping test because featureFlagChangeStreamPreAndPostImages feature flag is not enabled');
+ 'Skipping test because featureFlagChangeStreamPreAndPostImages or featureFlagClusteredIndexes feature flag is not enabled');
return;
}
diff --git a/jstests/change_streams/write_pit_preimage.js b/jstests/change_streams/write_pit_preimage.js
index acb175036d8..f19f992643f 100644
--- a/jstests/change_streams/write_pit_preimage.js
+++ b/jstests/change_streams/write_pit_preimage.js
@@ -3,6 +3,8 @@
// @tags: [
// requires_fcv_51,
// featureFlagChangeStreamPreAndPostImages,
+// # Clustered index support is required for change stream pre-images collection.
+// featureFlagClusteredIndexes,
// assumes_against_mongod_not_mongos,
// change_stream_does_not_expect_txns,
// multiversion_incompatible,
diff --git a/jstests/multiVersion/change_streams_pre_and_post_images_upgrade_downgrade.js b/jstests/multiVersion/change_streams_pre_and_post_images_upgrade_downgrade.js
index be15e6a89f2..60aaf51f050 100644
--- a/jstests/multiVersion/change_streams_pre_and_post_images_upgrade_downgrade.js
+++ b/jstests/multiVersion/change_streams_pre_and_post_images_upgrade_downgrade.js
@@ -1,7 +1,11 @@
/**
* Verifies that it is possible to upgrade a replica set with collections with 'recordPreImages'
* option to use 'changeStreamPreAndPostImages' option, and to do a corresponding downgrade.
- * @tags: [requires_fcv_51, featureFlagChangeStreamPreAndPostImages]
+ * @tags: [requires_fcv_51,
+ * featureFlagChangeStreamPreAndPostImages,
+ * # Clustered index support is required for change stream pre-images collection.
+ * featureFlagClusteredIndexes,
+ * ]
*/
(function() {
'use strict';
@@ -35,6 +39,16 @@ function runTest(downgradeVersion) {
rst.upgradeSet({binVersion: "latest"});
testDB = rst.getPrimary().getDB(jsTestName());
+ // Verify that an attempt to set 'changeStreamPreAndPostImages' option fails for the downgraded
+ // FCV version.
+ assert.commandFailedWithCode(
+ testDB.createCollection("anotherTestCollection",
+ {"changeStreamPreAndPostImages": {enabled: false}}),
+ 5846900);
+ assert.commandFailedWithCode(
+ testDB.runCommand({"collMod": collName, "changeStreamPreAndPostImages": {enabled: false}}),
+ 5846901);
+
// Set the FCV to the latest.
testDB.adminCommand({setFeatureCompatibilityVersion: latestFCV});
@@ -62,47 +76,8 @@ function runTest(downgradeVersion) {
// Downgrade the FCV.
testDB.adminCommand({setFeatureCompatibilityVersion: downgradeFCV});
- // Verify that an attempt to set 'changeStreamPreAndPostImages' option fails for the downgrade
- // version.
- assert.commandFailedWithCode(
- testDB.createCollection(collName, {"changeStreamPreAndPostImages": {enabled: false}}),
- 5846900);
- assert.commandFailedWithCode(
- testDB.runCommand({"collMod": collName, "changeStreamPreAndPostImages": {enabled: false}}),
- 5846901);
-
- // Downgrade the cluster.
- rst.upgradeSet({binVersion: downgradeVersion});
-
- // Reset the db reference.
- testDB = rst.getPrimary().getDB(jsTestName());
-
- // 'changeStreamPreAndPostImages' option must be absent and 'recordPreImages' should be set to
- // true.
- assertCollectionOptionIsEnabled(testDB, collName, "recordPreImages");
- assertChangeStreamPreAndPostImagesCollectionOptionIsAbsent(testDB, collName);
-
- // Upgrade the replica set.
- rst.upgradeSet({binVersion: "latest"});
- testDB = rst.getPrimary().getDB(jsTestName());
-
- // Set the FCV to the latest.
- testDB.adminCommand({setFeatureCompatibilityVersion: latestFCV});
-
- // Enable pre-/post-images for the collection with "recordPreImages" enabled.
- assert.commandWorked(
- testDB.runCommand({"collMod": collName, "changeStreamPreAndPostImages": {enabled: true}}));
-
- // 'changeStreamPreAndPostImages' option must be enabled and 'recordPreImages' option must be
- // absent.
- assertChangeStreamPreAndPostImagesCollectionOptionIsEnabled(testDB, collName);
- assertCollectionOptionIsAbsent(testDB, collName, "recordPreImages");
-
- // Downgrade the FCV.
- testDB.adminCommand({setFeatureCompatibilityVersion: downgradeFCV});
-
- // Downgrading the cluster should fail, since unsupported option 'changeStreamPreAndPostImages'
- // is enabled for the collection.
+ // Downgrading the cluster should fail, since the pre-images collection is clustered which is
+ // not supported by the downgraded binary.
try {
rst.upgradeSet({binVersion: downgradeVersion});
assert(false);
diff --git a/jstests/noPassthrough/change_streams_pre_and_post_images_in_create_and_collmod.js b/jstests/noPassthrough/change_streams_pre_and_post_images_in_create_and_collmod.js
index 71c90843d3d..8f27c8476d8 100644
--- a/jstests/noPassthrough/change_streams_pre_and_post_images_in_create_and_collmod.js
+++ b/jstests/noPassthrough/change_streams_pre_and_post_images_in_create_and_collmod.js
@@ -1,8 +1,14 @@
/*
* Tests that the 'changeStreamPreAndPostImages' option is settable via the collMod and create
* commands. Also tests that this option cannot be set on collections in the 'local', 'admin',
- * 'config' databases as well as timeseries and view collections.
- * @tags: [requires_fcv_51, featureFlagChangeStreamPreAndPostImages]
+ * 'config' databases as well as timeseries and view collections. Verifies that the pre-images
+ * collection is clustered.
+ * @tags: [
+ * requires_fcv_51,
+ * featureFlagChangeStreamPreAndPostImages,
+ * # Clustered index support is required for change stream pre-images collection.
+ * featureFlagClusteredIndexes,
+ * ]
*/
(function() {
'use strict';
@@ -39,16 +45,34 @@ const localDB = primary.getDB("local");
const configDB = primary.getDB("config");
const testDB = primary.getDB(dbName);
-function assertPreimagesCollectionIsAbsent() {
- const result = localDB.runCommand("listCollections", {filter: {name: preimagesCollName}});
+function findPreImagesCollectionDescriptions() {
+ return localDB.runCommand("listCollections", {filter: {name: preimagesCollName}});
+}
+
+function assertPreImagesCollectionIsAbsent() {
+ const result = findPreImagesCollectionDescriptions();
assert.eq(result.cursor.firstBatch.length, 0);
}
-function assertPreimagesCollectionExists() {
- const result = localDB.runCommand("listCollections", {filter: {name: preimagesCollName}});
+function assertPreImagesCollectionExists() {
+ const result = findPreImagesCollectionDescriptions();
assert.eq(result.cursor.firstBatch[0].name, preimagesCollName);
}
+// Verifies that the pre-images collection is clustered by _id.
+function assertPreImagesCollectionIsClustered() {
+ const collectionInfos = findPreImagesCollectionDescriptions();
+ assert.eq(collectionInfos.cursor.firstBatch.length, 1, collectionInfos);
+ const preImagesCollectionDescription = collectionInfos.cursor.firstBatch[0];
+ assert(preImagesCollectionDescription.hasOwnProperty("options"),
+ preImagesCollectionDescription);
+ assert(preImagesCollectionDescription.options.hasOwnProperty("clusteredIndex"),
+ preImagesCollectionDescription);
+ const clusteredIndexDescription = preImagesCollectionDescription.options.clusteredIndex;
+ assert.eq(clusteredIndexDescription.unique, true, preImagesCollectionDescription);
+ assert.eq(clusteredIndexDescription.key, {_id: 1}, preImagesCollectionDescription);
+}
+
// Check that we cannot set 'changeStreamPreAndPostImages' on the local, admin and config databases.
for (const db of [localDB, adminDB, configDB]) {
assert.commandFailedWithCode(
@@ -63,7 +87,7 @@ for (const db of [localDB, adminDB, configDB]) {
// Drop the pre-images collection.
assertDropCollection(localDB, preimagesCollName);
-assertPreimagesCollectionIsAbsent();
+assertPreImagesCollectionIsAbsent();
// Drop all collections that are used during the test.
for (const collectionToDelete
@@ -75,23 +99,24 @@ for (const collectionToDelete
assert.commandWorked(
testDB.runCommand({create: collName, changeStreamPreAndPostImages: {enabled: true}}));
assertChangeStreamPreAndPostImagesCollectionOptionIsEnabled(testDB, collName);
-assertPreimagesCollectionExists();
+assertPreImagesCollectionExists();
+assertPreImagesCollectionIsClustered();
// Drop the pre-images collection.
assertDropCollection(localDB, preimagesCollName);
-assertPreimagesCollectionIsAbsent();
+assertPreImagesCollectionIsAbsent();
assert.commandWorked(testDB.runCommand({create: collName2}));
assert.commandWorked(
testDB.runCommand({collMod: collName2, changeStreamPreAndPostImages: {enabled: true}}));
assertChangeStreamPreAndPostImagesCollectionOptionIsEnabled(testDB, collName2);
-assertPreimagesCollectionExists();
+assertPreImagesCollectionExists();
// Verify that setting collection options with 'collMod' command does not affect
// 'changeStreamPreAndPostImages' option.
assert.commandWorked(testDB.runCommand({"collMod": collName2, validationLevel: "off"}));
assertChangeStreamPreAndPostImagesCollectionOptionIsEnabled(testDB, collName2);
-assertPreimagesCollectionExists();
+assertPreImagesCollectionExists();
// Should successfully disable 'changeStreamPreAndPostImages' using the 'collMod' command.
assert.commandWorked(
@@ -100,7 +125,7 @@ assertChangeStreamPreAndPostImagesCollectionOptionIsAbsent(testDB, collName2);
// Should not remove the pre-images collection on disabling 'changeStreamPreAndPostImages'
// option.
-assertPreimagesCollectionExists();
+assertPreImagesCollectionExists();
// Both 'recordPreImages' and 'changeStreamPreAndPostImages' may not be enabled at the same
// time.
diff --git a/src/mongo/db/catalog/create_collection.cpp b/src/mongo/db/catalog/create_collection.cpp
index 0c71a02e4cf..a238779222c 100644
--- a/src/mongo/db/catalog/create_collection.cpp
+++ b/src/mongo/db/catalog/create_collection.cpp
@@ -620,11 +620,22 @@ void createChangeStreamPreImagesCollection(OperationContext* opCtx) {
uassert(5868501,
"Failpoint failPreimagesCollectionCreation enabled. Throwing exception",
!MONGO_unlikely(failPreimagesCollectionCreation.shouldFail()));
+ tassert(5882500,
+ "Failed to create the pre-images collection: clustered indexes feature is not enabled",
+ feature_flags::gClusteredIndexes.isEnabled(serverGlobalParams.featureCompatibility));
const auto nss = NamespaceString::kChangeStreamPreImagesNamespace;
- const auto status = _createCollection(opCtx, nss, CollectionOptions(), BSONObj());
+ CollectionOptions preImagesCollectionOptions;
+
+ // Make the collection clustered by _id.
+ auto preImagesCollectionKey = BSON("_id" << 1);
+ preImagesCollectionOptions.clusteredIndex.emplace(
+ ClusteredIndexSpec{preImagesCollectionKey, true /*unique*/}, false /*legacyFormat*/);
+ const auto status =
+ _createCollection(opCtx, nss, std::move(preImagesCollectionOptions), BSONObj());
uassert(status.code(),
- str::stream() << "Failed to create the pre-images collection: " << nss.coll(),
+ str::stream() << "Failed to create the pre-images collection: " << nss.coll()
+ << causedBy(status.reason()),
status.isOK() || status.code() == ErrorCodes::NamespaceExists);
}
diff --git a/src/mongo/db/catalog/create_collection.h b/src/mongo/db/catalog/create_collection.h
index 3b68acbfe2a..24d41eb3fbd 100644
--- a/src/mongo/db/catalog/create_collection.h
+++ b/src/mongo/db/catalog/create_collection.h
@@ -55,6 +55,10 @@ Status createCollection(OperationContext* opCtx,
const NamespaceString& ns,
const CreateCommand& cmd);
+/**
+ * Creates the change stream pre-images collection. The collection is clustered by the primary key,
+ * _id.
+ */
void createChangeStreamPreImagesCollection(OperationContext* opCtx);
/**