SERVER-112969 Skip CheckReplDBHash index check for regular collection with accompanying buckets namespace (#43454)

GitOrigin-RevId: 21868c0e7bbe6f49b638e31e403092f0eb81f6a8
This commit is contained in:
Joan Bruguera Micó (at MongoDB) 2025-11-04 14:17:31 +00:00 committed by MongoDB Bot
parent 3c9c2f2747
commit 397eb0bcb4
2 changed files with 48 additions and 31 deletions

View File

@ -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.'),

View File

@ -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 =