diff options
Diffstat (limited to 'jstests/noPassthrough/initial_sync_same_index_spec.js')
| -rw-r--r-- | jstests/noPassthrough/initial_sync_same_index_spec.js | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/jstests/noPassthrough/initial_sync_same_index_spec.js b/jstests/noPassthrough/initial_sync_same_index_spec.js new file mode 100644 index 00000000000..5746a6091b3 --- /dev/null +++ b/jstests/noPassthrough/initial_sync_same_index_spec.js @@ -0,0 +1,98 @@ +/** + * Test that initial sync does not fail if an identical index spec is created, dropped and + * recreated. + */ + +(function() { +"use strict"; + +load("jstests/libs/fail_point_util.js"); // for kDefaultWaitForFailPointTimeout + +const testName = "initial_sync_same_index_spec"; +const dbName = testName; +const collName = "testcoll"; + +// Set up a stable two node replica set. +let replTest = new ReplSetTest({ + name: testName, + nodes: [{}, {rsConfig: {priority: 0, votes: 0}}], +}); +replTest.startSet(); +replTest.initiateWithHighElectionTimeout(); + +let primary = replTest.getPrimary(); +let secondary = replTest.getSecondary(); + +let primaryDB = primary.getDB(dbName); +let secondaryDB = secondary.getDB(dbName); + +let primaryColl = primaryDB[collName]; +let secondaryColl = secondaryDB[collName]; + +// Insert data into the collection for initial sync to copy. +assert.commandWorked(primaryColl.insert([{_id: 1, a: 1}, {_id: 2, a: 2}])); + +// Set WC to 1. The default WC is majority and the replica set will not be able to satisfy majority +// index create/drop later. +assert.commandWorked(primary.adminCommand( + {setDefaultRWConcern: 1, defaultWriteConcern: {w: 1}, writeConcern: {w: "majority"}})); + +/** + * Restart the the secondary with no data in order to provoke an initial sync from the primary. + * Use startup setParameter to set failpoints to pause the initial sync before indexes are fetched. + */ + +const fp = 'hangBeforeClonerStage'; +let secondaryStartupParams = {}; +secondaryStartupParams['failpoint.' + fp] = tojson({ + mode: 'alwaysOn', + data: {cloner: "CollectionCloner", stage: "listIndexes", nss: primaryColl.getFullName()} +}); + +// Only try initial sync once, so any failure syncing indexes will be surfaced. +secondaryStartupParams['numInitialSyncAttempts'] = 1; + +const startupOptions = { + startClean: true, + setParameter: secondaryStartupParams +}; + +jsTestLog( + "Restarting the the secondary with no data in order to provoke an initial sync from the " + + "primary. Using startup options: " + tojson(startupOptions)); +secondary = replTest.restart(secondary, startupOptions); +secondaryDB = secondary.getDB(dbName); +secondaryColl = secondaryDB[collName]; + +jsTestLog("Waiting for secondary to reach failPoint '" + fp + "'"); +assert.commandWorked(secondary.adminCommand( + {waitForFailPoint: fp, timesEntered: 1, maxTimeMS: kDefaultWaitForFailPointTimeout})); + +// Restarting the secondary may have resulted in an election. Wait until the system stabilizes and +// reaches RS_STARTUP2 state. +replTest.getPrimary(); +replTest.waitForState(secondary, ReplSetTest.State.STARTUP_2); + +/** + * Now that the secondary is hanging in initial sync, create, drop and recreate identical indexes to + * ensure it is correctly handled by initial sync (when the failpoint is removed). + */ + +jsTestLog("Creating index on the primary."); +assert.commandWorked(primaryColl.createIndex({a: 1}, {name: "a1"})); + +jsTestLog("Dropping index on the primary."); +assert.commandWorked(primaryColl.dropIndex("a1")); + +jsTestLog("Recreating index with same spec on the primary."); +assert.commandWorked(primaryColl.createIndex({a: 1}, {name: "a2"})); + +jsTestLog("Allowing secondary initial sync to resume."); +assert.commandWorked( + secondary.adminCommand({configureFailPoint: "hangBeforeClonerStage", mode: 'off'})); + +jsTestLog("Waiting for initial sync to complete successfully."); +replTest.waitForState(secondary, ReplSetTest.State.SECONDARY); + +replTest.stopSet(); +})(); |
