mirror of
https://github.com/mongodb/mongo.git
synced 2024-12-01 09:32:32 +01:00
82 lines
2.9 KiB
JavaScript
82 lines
2.9 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.
|
|
*/
|
|
|
|
(function() {
|
|
'use strict';
|
|
|
|
load('jstests/libs/fail_point_util.js');
|
|
load('jstests/noPassthrough/libs/index_build.js');
|
|
|
|
const dbName = 'test';
|
|
const collectionName = 'coll';
|
|
|
|
// How many documents to insert on the primary prior to
|
|
// starting initial-sync.
|
|
const initialDocs = 10;
|
|
// Batch-size used for cloning.
|
|
// Used as a fail-point parameter as detailed below.
|
|
const clonerBatchSize = 1;
|
|
|
|
// Setting initialDocs larger than clonerBatchSize causes
|
|
// the fail-point to be hit because we fetch
|
|
// multiple batches in the InitialSyncer.
|
|
|
|
// 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},
|
|
});
|
|
secondary.setSecondaryOk();
|
|
const secondaryColl = secondary.getDB(dbName).getCollection(collectionName);
|
|
|
|
// We set the collectionClonerBatchSize low above, so we will definitely hit
|
|
// this fail-point and hang after the first batch is applied. While the
|
|
// secondary is hung we clone the problematic document.
|
|
const failPoint = configureFailPoint(
|
|
secondary, 'initialSyncHangBeforeCopyingDatabases', {nss: secondaryColl.getFullName()});
|
|
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();
|
|
})();
|