summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Schultz <william.schultz@mongodb.com>2019-09-25 15:19:24 +0000
committerevergreen <evergreen@mongodb.com>2019-09-25 15:19:24 +0000
commitc41af3e315a115b04a53706837d36a729d174fc3 (patch)
treec39327e225d6bf77d6e45916a1178066b0701e4d
parent6db227bc5616d6af031a797d87eaad193c8c32f0 (diff)
downloadmongo-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.js36
-rw-r--r--src/mongo/db/repl/collection_bulk_loader_impl.cpp22
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();