diff options
author | William Schultz <william.schultz@mongodb.com> | 2019-10-01 21:24:44 +0000 |
---|---|---|
committer | evergreen <evergreen@mongodb.com> | 2019-10-01 21:24:44 +0000 |
commit | ffc20cf1b310ebc22bab64f9627f558b78d58d57 (patch) | |
tree | 55c5b388b08f041b9b69117c58a4288ab219bde3 | |
parent | f27579ad4400d5e8ab7a79fc607c1e39438eb146 (diff) | |
download | mongo-ffc20cf1b310ebc22bab64f9627f558b78d58d57.tar.gz |
SERVER-42484 Ensure we are inside a WriteUnitOfWork when writing index keys during initial sync collection cloning
(cherry picked from commit c41af3e315a115b04a53706837d36a729d174fc3)
-rw-r--r-- | jstests/replsets/initial_sync_clone_multikey.js | 36 | ||||
-rw-r--r-- | src/mongo/db/repl/collection_bulk_loader_impl.cpp | 17 |
2 files changed, 50 insertions, 3 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..0cf39825261 --- /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(); +})();
\ No newline at end of file diff --git a/src/mongo/db/repl/collection_bulk_loader_impl.cpp b/src/mongo/db/repl/collection_bulk_loader_impl.cpp index 68f760d284a..56322162fe1 100644 --- a/src/mongo/db/repl/collection_bulk_loader_impl.cpp +++ b/src/mongo/db/repl/collection_bulk_loader_impl.cpp @@ -154,9 +154,20 @@ Status CollectionBulkLoaderImpl::insertDocuments(const std::vector<BSONObj>::con } if (loc) { - // Inserts index entries into the external sorter. This will not update - // pre-existing indexes. - status = _addDocumentToIndexBlocks(doc, loc.get()); + // 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()); + status = _addDocumentToIndexBlocks(doc, loc.get()); + // We only need to commit the unit of work if the index insertion was + // successful. + if (status.isOK()) { + wunit.commit(); + } + return status; + }); } if (!status.isOK()) { |