diff options
author | William Schultz <william.schultz@mongodb.com> | 2019-09-25 15:19:24 +0000 |
---|---|---|
committer | evergreen <evergreen@mongodb.com> | 2019-09-25 15:19:24 +0000 |
commit | c41af3e315a115b04a53706837d36a729d174fc3 (patch) | |
tree | c39327e225d6bf77d6e45916a1178066b0701e4d | |
parent | 6db227bc5616d6af031a797d87eaad193c8c32f0 (diff) | |
download | mongo-c41af3e315a115b04a53706837d36a729d174fc3.tar.gz |
SERVER-42484 Ensure we are inside a WriteUnitOfWork when writing index keys during initial sync collection cloning
-rw-r--r-- | jstests/replsets/initial_sync_clone_multikey.js | 36 | ||||
-rw-r--r-- | src/mongo/db/repl/collection_bulk_loader_impl.cpp | 22 |
2 files changed, 52 insertions, 6 deletions
diff --git a/jstests/replsets/initial_sync_clone_multikey.js b/jstests/replsets/initial_sync_clone_multikey.js new file mode 100644 index 00000000000..a9228ac8502 --- /dev/null +++ b/jstests/replsets/initial_sync_clone_multikey.js @@ -0,0 +1,36 @@ +/** + * Test initial sync cloning of a collection that contains a multikey index when hybrid index builds + * are disabled. + */ +(function() { +"use strict"; + +const replTest = new ReplSetTest({nodes: 1}); +replTest.startSet(); +replTest.initiate(); + +const dbName = jsTest.name(); +const collName = "test"; + +const primary = replTest.getPrimary(); +const primaryDB = primary.getDB(dbName); + +jsTestLog("Creating the collection and an index."); +assert.commandWorked(primaryDB.createCollection(collName)); +assert.commandWorked(primaryDB[collName].createIndex({"x": 1}, {background: true})); + +// Make the index multikey. +primaryDB[collName].insert({x: [1, 2]}); + +jsTestLog("Adding a secondary node to do the initial sync."); +replTest.add({setParameter: "enableHybridIndexBuilds=false"}); + +jsTestLog("Re-initiating replica set with the new secondary."); +replTest.reInitiate(); + +// Wait until initial sync completes. +jsTestLog("Waiting until initial sync completes."); +replTest.awaitSecondaryNodes(); +replTest.awaitReplication(); +replTest.stopSet(); +})(); diff --git a/src/mongo/db/repl/collection_bulk_loader_impl.cpp b/src/mongo/db/repl/collection_bulk_loader_impl.cpp index 81bfef20622..29f82e61768 100644 --- a/src/mongo/db/repl/collection_bulk_loader_impl.cpp +++ b/src/mongo/db/repl/collection_bulk_loader_impl.cpp @@ -150,13 +150,23 @@ Status CollectionBulkLoaderImpl::_insertDocumentsForUncappedCollection( return status; } - // Inserts index entries into the external sorter. This will not update - // pre-existing indexes. - for (size_t index = 0; index < locs.size(); ++index) { - status = _addDocumentToIndexBlocks(*iter++, locs.at(index)); - if (!status.isOK()) { - return status; + // Inserts index entries into the external sorter. This will not update pre-existing + // indexes. Wrap this in a WUOW since the index entry insertion may modify the durable + // record store which can throw a write conflict exception. + status = writeConflictRetry(_opCtx.get(), "_addDocumentToIndexBlocks", _nss.ns(), [&] { + WriteUnitOfWork wunit(_opCtx.get()); + for (size_t index = 0; index < locs.size(); ++index) { + status = _addDocumentToIndexBlocks(*iter++, locs.at(index)); + if (!status.isOK()) { + return status; + } } + wunit.commit(); + return Status::OK(); + }); + + if (!status.isOK()) { + return status; } } return Status::OK(); |