Files
mongo/jstests/replsets/initial_sync_index_conflict.js
Matt Broadstone 771dabd098 SERVER-81339 Convert ReplSetTest and ShardingTest to modules (#26332)
GitOrigin-RevId: 744aa110a53786b23c62ff53f87a1418b5991e8d
2024-08-20 22:00:49 +00:00

65 lines
2.4 KiB
JavaScript

/**
* Asserts that applying a single-phase createIndexes oplog entry doesn't cause initial-sync to fail
* if there is an ongoing two-phase index build started by the cloner with the same index specs.
* This may happen if the index was first created on the primary when the collection was empty, then
* subsequently dropped and recreated after the collection has documents.
*/
import {configureFailPoint} from "jstests/libs/fail_point_util.js";
import {ReplSetTest} from "jstests/libs/replsettest.js";
import {IndexBuildTest} from "jstests/noPassthrough/libs/index_build.js";
const dbName = 'test';
const collectionName = 'coll';
// Start one-node repl-set.
const rst = new ReplSetTest({nodes: 1});
rst.startSet();
rst.initiate();
const primary = rst.getPrimary();
const primaryDB = primary.getDB(dbName);
const primaryColl = primaryDB.getCollection(collectionName);
// Add a secondary.
const secondary = rst.add({
rsConfig: {votes: 0, priority: 0},
setParameter: {numInitialSyncAttempts: 1},
});
// While the secondary is hung, we create the same index multiple times to
// reproduce the interaction between single and two phase index builds on the
// same index.
const failPoint = configureFailPoint(secondary, 'initialSyncHangBeforeCopyingDatabases');
rst.reInitiate();
failPoint.wait();
// Create the index using the empty collection fast path. The index build should be replicated
// in a single createIndexes oplog entry.
assert.commandWorked(primaryColl.createIndex({a: 1}));
assert.commandWorked(primaryColl.insert({_id: 0, a: 0}));
// Start a two-phase index build using the same spec when the collection has documents.
// Use a failpoint to keep the index build from finishing when we resume initial sync on
// the secondary.
assert.commandWorked(primaryColl.dropIndex({a: 1}));
IndexBuildTest.pauseIndexBuilds(primary);
IndexBuildTest.pauseIndexBuilds(secondary);
const createIdx = IndexBuildTest.startIndexBuild(primary, primaryColl.getFullName(), {a: 1});
IndexBuildTest.waitForIndexBuildToScanCollection(primaryDB, primaryColl.getName(), 'a_1');
try {
// Resume initial sync. The createIndexes oplog entry will be applied.
failPoint.off();
// Wait for initial sync to finish.
rst.awaitSecondaryNodes();
} finally {
IndexBuildTest.resumeIndexBuilds(secondary);
IndexBuildTest.resumeIndexBuilds(primary);
createIdx();
}
IndexBuildTest.assertIndexes(primaryColl, 2, ['_id_', 'a_1']);
rst.stopSet();