diff --git a/src/mongo/db/catalog/index_create.cpp b/src/mongo/db/catalog/index_create.cpp index 1b2b3068530a6..0814277262fb3 100644 --- a/src/mongo/db/catalog/index_create.cpp +++ b/src/mongo/db/catalog/index_create.cpp @@ -259,6 +259,8 @@ Status MultiIndexBlock::insertAllDocumentsInCollection(std::set* dupsO WriteUnitOfWork wunit(_txn); Status ret = insert(objToIndex.value(), loc); + if (_buildInBackground) + exec->saveState(); if (ret.isOK()) { wunit.commit(); } else if (dupsOut && ret.code() == ErrorCodes::DuplicateKey) { @@ -269,6 +271,8 @@ Status MultiIndexBlock::insertAllDocumentsInCollection(std::set* dupsO // Fail the index build hard. return ret; } + if (_buildInBackground) + exec->restoreState(); // Handles any WCEs internally. // Go to the next document progress->hit(); diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp index fa778f71551dd..2320672fe196d 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp @@ -1069,8 +1069,17 @@ void WiredTigerIndexUnique::_unindex(WT_CURSOR* c, // dups are allowed, so we have to deal with a vector of RecordIds. int ret = WT_OP_CHECK(c->search(c)); - if (ret == WT_NOTFOUND) + if (ret == WT_NOTFOUND) { + // WT_NOTFOUND is only expected during a background index build. Insert a dummy value and + // delete it again to trigger a write conflict in case this is being concurrently indexed by + // the background indexer. + c->set_key(c, keyItem.Get()); + c->set_value(c, emptyItem.Get()); + invariantWTOK(WT_OP_CHECK(c->insert(c))); + c->set_key(c, keyItem.Get()); + invariantWTOK(WT_OP_CHECK(c->remove(c))); return; + } invariantWTOK(ret); WT_ITEM old; @@ -1178,6 +1187,15 @@ void WiredTigerIndexStandard::_unindex(WT_CURSOR* c, int ret = WT_OP_CHECK(c->remove(c)); if (ret != WT_NOTFOUND) { invariantWTOK(ret); + } else { + // WT_NOTFOUND is only expected during a background index build. Insert a dummy value and + // delete it again to trigger a write conflict in case this is being concurrently indexed by + // the background indexer. + c->set_key(c, item.Get()); + c->set_value(c, emptyItem.Get()); + invariantWTOK(WT_OP_CHECK(c->insert(c))); + c->set_key(c, item.Get()); + invariantWTOK(WT_OP_CHECK(c->remove(c))); } }