summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis Williams <louis.williams@mongodb.com>2020-04-07 18:10:57 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-04-10 19:24:32 +0000
commit61c58c415c5f0ec2b8948f54b95b0ec48659b6a2 (patch)
treea8268463244baefda03b00737ce5a9897c16d9d8
parent98be6002347d03644c7a68259ac5b0930edc6ba7 (diff)
downloadmongo-61c58c415c5f0ec2b8948f54b95b0ec48659b6a2.tar.gz
SERVER-47407 Avoid using WriteUnitOfWork in index build collection scan loop
(cherry picked from commit e9379fcee79456d3795b598ccad91a0694007d0e)
-rw-r--r--src/mongo/db/catalog/multi_index_block.cpp24
-rw-r--r--src/mongo/db/index/skipped_record_tracker.cpp4
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp3
3 files changed, 22 insertions, 9 deletions
diff --git a/src/mongo/db/catalog/multi_index_block.cpp b/src/mongo/db/catalog/multi_index_block.cpp
index e6e8c96b01c..e1f2589027e 100644
--- a/src/mongo/db/catalog/multi_index_block.cpp
+++ b/src/mongo/db/catalog/multi_index_block.cpp
@@ -504,21 +504,27 @@ Status MultiIndexBlock::insertAllDocumentsInCollection(OperationContext* opCtx,
failPointHangDuringBuild(&hangBeforeIndexBuildOf, "before", objToIndex.value());
- WriteUnitOfWork wunit(opCtx);
- Status ret = insert(opCtx, objToIndex.value(), loc);
- if (_method == IndexBuildMethod::kBackground)
- exec->saveState();
- if (!ret.isOK()) {
- // Fail the index build hard.
- return ret;
- }
- wunit.commit();
if (_method == IndexBuildMethod::kBackground) {
+ WriteUnitOfWork wunit(opCtx);
+
+ Status ret = insert(opCtx, objToIndex.value(), loc);
+ if (!ret.isOK()) {
+ return ret;
+ }
+ exec->saveState();
+ wunit.commit();
try {
exec->restoreState(); // Handles any WCEs internally.
} catch (...) {
return exceptionToStatus();
}
+ } else {
+ // The external sorter is not part of the storage engine and therefore does not need
+ // a WriteUnitOfWork to write keys.
+ Status ret = insert(opCtx, objToIndex.value(), loc);
+ if (!ret.isOK()) {
+ return ret;
+ }
}
failPointHangDuringBuild(&hangAfterIndexBuildOf, "after", objToIndex.value());
diff --git a/src/mongo/db/index/skipped_record_tracker.cpp b/src/mongo/db/index/skipped_record_tracker.cpp
index d9442b52540..f7c401c12e5 100644
--- a/src/mongo/db/index/skipped_record_tracker.cpp
+++ b/src/mongo/db/index/skipped_record_tracker.cpp
@@ -55,10 +55,14 @@ void SkippedRecordTracker::record(OperationContext* opCtx, const RecordId& recor
_skippedRecordsTable =
opCtx->getServiceContext()->getStorageEngine()->makeTemporaryRecordStore(opCtx);
}
+ // A WriteUnitOfWork may not already be active if the originating operation was part of an
+ // insert into the external sorter.
+ WriteUnitOfWork wuow(opCtx);
uassertStatusOK(
_skippedRecordsTable->rs()
->insertRecord(opCtx, toInsert.objdata(), toInsert.objsize(), Timestamp::min())
.getStatus());
+ wuow.commit();
}
bool SkippedRecordTracker::areAllRecordsApplied(OperationContext* opCtx) const {
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp
index dc5122b3f8c..8ecd854e399 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp
@@ -1016,6 +1016,7 @@ bool WiredTigerRecordStore::findRecord(OperationContext* opCtx,
void WiredTigerRecordStore::deleteRecord(OperationContext* opCtx, const RecordId& id) {
dassert(opCtx->lockState()->isWriteLocked());
+ invariant(opCtx->lockState()->inAWriteUnitOfWork() || opCtx->lockState()->isNoop());
// Deletes should never occur on a capped collection because truncation uses
// WT_SESSION::truncate().
@@ -1424,6 +1425,7 @@ Status WiredTigerRecordStore::_insertRecords(OperationContext* opCtx,
const Timestamp* timestamps,
size_t nRecords) {
dassert(opCtx->lockState()->isWriteLocked());
+ invariant(opCtx->lockState()->inAWriteUnitOfWork() || opCtx->lockState()->isNoop());
// We are kind of cheating on capped collections since we write all of them at once ....
// Simplest way out would be to just block vector writes for everything except oplog ?
@@ -1569,6 +1571,7 @@ Status WiredTigerRecordStore::updateRecord(OperationContext* opCtx,
const char* data,
int len) {
dassert(opCtx->lockState()->isWriteLocked());
+ invariant(opCtx->lockState()->inAWriteUnitOfWork() || opCtx->lockState()->isNoop());
WiredTigerCursor curwrap(_uri, _tableId, true, opCtx);
curwrap.assertInActiveTxn();