diff --git a/jstests/concurrency/fsm_workloads/timeseries/timeseries_create_indexes.js b/jstests/concurrency/fsm_workloads/timeseries/timeseries_create_indexes.js index c9613da23c4..434346f3663 100644 --- a/jstests/concurrency/fsm_workloads/timeseries/timeseries_create_indexes.js +++ b/jstests/concurrency/fsm_workloads/timeseries/timeseries_create_indexes.js @@ -7,8 +7,6 @@ * excluded_from_simulate_crash_suites, * # TODO SERVER-105270 enable test in viewless timeseries suites * does_not_support_viewless_timeseries_yet, - * # TODO SERVER-105492 enable test in multiversion suites - * multiversion_incompatible, * # TODO SERVER-105509 enable test in config shard suites * config_shard_incompatible, * ] @@ -34,6 +32,14 @@ function getRandomCollection(db) { return db[collPrefix + Random.randInt(collCount)]; } +// TODO(SERVER-109819): Remove once v9.0 is last LTS +// Since binary v8.2, index operations either take a single lock, or re-check the UUID when +// re-acquiring the lock and return CollectionUUIDMismatch if the collection was dropped. +// Older binaries don't do this, so they can return more error codes. +const isPreV82Binary = TestData.multiversionBinVersion && + MongoRunner.compareBinVersions(MongoRunner.getBinVersionFor(TestData.multiversionBinVersion), + "8.2") < 0; + export const $config = (function() { var data = {nsPrefix: "create_idx_", numCollections: 5}; @@ -70,6 +76,8 @@ export const $config = (function() { 9748800, 9748801, 9748802, + // v8.1 may return this because it only has 1 out of 2 commits for SERVER-97488 + ...(isPreV82Binary ? [ErrorCodes.CollectionUUIDMismatch] : []), // If the collection already exists and is a view // TODO SERVER-85548 this should never happen ErrorCodes.NamespaceExists, @@ -104,6 +112,7 @@ export const $config = (function() { assert.commandWorkedOrFailedWithCode(coll.createIndex(indexSpec), [ // The collection has been concurrently dropped and recreated ErrorCodes.CollectionUUIDMismatch, + ...(isPreV82Binary ? [ErrorCodes.IllegalOperation] : []), ErrorCodes.IndexBuildAborted, // If the collection already exists and is a view // TODO SERVER-85548 this should never happen @@ -129,7 +138,17 @@ export const $config = (function() { }, checkIndexes: function(db, collName) { const coll = getRandomCollection(db); - const indexes = coll.getIndexes(); + let indexes; + try { + indexes = coll.getIndexes(); + } catch (err) { + // Binaries before v8.2 return this error if a regular collection gets dropped + // then re-created as timeseries during the listIndexes command. + if (isPreV82Binary && err.code == ErrorCodes.CommandNotSupportedOnView) { + return; + } + throw err; + } indexes.forEach(index => { Object.keys(index.key).forEach(indexKey => { assert(!indexKey.startsWith('control.'), diff --git a/src/mongo/shell/data_consistency_checker.js b/src/mongo/shell/data_consistency_checker.js index 612674ca021..0d378a38829 100644 --- a/src/mongo/shell/data_consistency_checker.js +++ b/src/mongo/shell/data_consistency_checker.js @@ -31,14 +31,6 @@ class CollInfos { this.collInfosRes = this.collInfosRes.filter(info => desiredCollNames.includes(info.name)); } - /** - * Get names for the clustered collections. - */ - getClusteredCollNames() { - const infos = this.collInfosRes.filter(info => info.options.clusteredIndex); - return infos.map(info => info.name); - } - hostAndNS(collName) { return `${this.conn.host}--${this.ns(collName)}`; } @@ -547,24 +539,34 @@ class DataConsistencyChecker { return true; }; - // Returns true if we should skip comparing the index count between the source and the - // syncing node for a clustered collection. 6.1 added clustered indexes into collStat - // output. There will be a difference in the nindex count between versions before and - // after 6.1. So, skip comparing across 6.1 for clustered collections. - const skipIndexCountCheck = function(sourceCollInfos, syncingCollInfos, collName) { + // If there is a regular collection `coll` and a legacy timeseries buckets collection + // `system.buckets.coll` on the same namespace (see SERVER-90862), the listIndexes command + // returns the indexes for `system.buckets.coll` in v8.2+ and `coll` in previous versions. + // This causes the CheckReplDBHash hook to report an inconsistency where there is none. + // Returns true if we should skip comparing the indexes due to this situation. + // TODO(SERVER-101594): Remove this workaround once only viewless timeseries exist. + const skipIndexesCheck = function( + sourceCollInfos, syncingCollInfos, sourceCollections, collName) { const sourceVersion = sourceCollInfos.binVersion; const syncingVersion = syncingCollInfos.binVersion; - // If both versions are before 6.1 or both are 6.1 onwards, we are good. - if ((MongoRunner.compareBinVersions(sourceVersion, "6.1") === -1 && - MongoRunner.compareBinVersions(syncingVersion, "6.1") === -1) || - (MongoRunner.compareBinVersions(sourceVersion, "6.1") >= 0 && - MongoRunner.compareBinVersions(syncingVersion, "6.1") >= 0)) { + // If both versions are before 8.2 or both are 8.2 onwards, we are good. + if ((MongoRunner.compareBinVersions(sourceVersion, "8.2") === -1 && + MongoRunner.compareBinVersions(syncingVersion, "8.2") === -1) || + (MongoRunner.compareBinVersions(sourceVersion, "8.2") >= 0 && + MongoRunner.compareBinVersions(syncingVersion, "8.2") >= 0)) { return false; } - // Skip if this is a clustered collection - if (sourceCollInfos.getClusteredCollNames().includes(collName)) { + // Skip if both ${collName} and system.buckets.${collName} exist due to SERVER-90862. + const bucketsCollName = "system.buckets." + collName; + if (sourceCollections.includes(bucketsCollName)) { + prettyPrint( + `Skipping comparison of indexes for collection ${dbName}.${ + collName} because a buckets collection exists at ${dbName}.${ + bucketsCollName}. Versions ${sourceCollInfos.binVersion} and ${ + syncingCollInfos.binVersion} are expected to differ in the index specs.`, + ); return true; } @@ -614,14 +616,10 @@ class DataConsistencyChecker { indexDiffs.indexesMissingOnSyncing.length > 0 || indexDiffs.indexesWithDifferentSpecs.length > 0; } - if (skipIndexCountCheck(sourceCollInfos, syncingCollInfos, collName)) { - prettyPrint(`Skipping comparison of collStats.nindex for clustered collection ${ - dbName}.${collName}. Versions ${sourceCollInfos.binVersion} and ${ - syncingCollInfos.binVersion} are expected to differ in the nindex count.`); - } else if (syncingHasIndexes && - (sourceCollStats.nindexes !== syncingCollStats.nindexes || - indexSpecsDiffer)) { - reasons.push('indexes'); + if (syncingHasIndexes && + !skipIndexesCheck(sourceCollInfos, syncingCollInfos, sourceCollections, collName) && + (sourceCollStats.nindexes !== syncingCollStats.nindexes || indexSpecsDiffer)) { + reasons.push("indexes"); } const indexBuildsMatch =