From 1eb3e9a9b1b9792e04351ab6fd72438071560975 Mon Sep 17 00:00:00 2001 From: Benety Goh Date: Wed, 23 Oct 2019 14:24:40 +0000 Subject: SERVER-44121 IndexBuildInterceptor::drainWritesIntoIndex() yields locks only when directly by drain yield policy --- src/mongo/db/index/index_build_interceptor.cpp | 21 ++++++--------------- src/mongo/db/index/index_build_interceptor.h | 5 ++--- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/mongo/db/index/index_build_interceptor.cpp b/src/mongo/db/index/index_build_interceptor.cpp index fecbc5974ca..47ce29006c8 100644 --- a/src/mongo/db/index/index_build_interceptor.cpp +++ b/src/mongo/db/index/index_build_interceptor.cpp @@ -236,8 +236,11 @@ Status IndexBuildInterceptor::drainWritesIntoIndex(OperationContext* opCtx, progress->hit(batchSize); _numApplied += batchSize; - // Lock yielding will only happen if we are holding intent locks. - _tryYield(opCtx); + // Lock yielding will be directed by the yield policy provided. + // We will typically yield locks during the draining phase if we are holding intent locks. + if (DrainYieldPolicy::kYield == drainYieldPolicy) { + _yield(opCtx); + } // Account for more writes coming in during a batch. progress->setTotalWhileRunning(_sideWritesCounter->loadRelaxed() - appliedAtStart); @@ -329,19 +332,7 @@ Status IndexBuildInterceptor::_applyWrite(OperationContext* opCtx, return Status::OK(); } -void IndexBuildInterceptor::_tryYield(OperationContext* opCtx) { - // Never yield while holding locks that prevent writes to the collection: only yield while - // holding intent locks. This check considers all locks in the hierarchy that would cover this - // mode. - const NamespaceString nss(_indexCatalogEntry->ns()); - if (opCtx->lockState()->isCollectionLockedForMode(nss, MODE_S)) { - return; - } - if (kDebugBuild) { - invariant(!opCtx->lockState()->isCollectionLockedForMode(nss, MODE_X)); - invariant(!opCtx->lockState()->isDbLockedForMode(nss.db(), MODE_X)); - } - +void IndexBuildInterceptor::_yield(OperationContext* opCtx) { // Releasing locks means a new snapshot should be acquired when restored. opCtx->recoveryUnit()->abandonSnapshot(); diff --git a/src/mongo/db/index/index_build_interceptor.h b/src/mongo/db/index/index_build_interceptor.h index c41e7267580..32fede378a0 100644 --- a/src/mongo/db/index/index_build_interceptor.h +++ b/src/mongo/db/index/index_build_interceptor.h @@ -151,10 +151,9 @@ private: int64_t* const keysDeleted); /** - * Yield lock manager locks, but only when holding intent locks. Does nothing otherwise. If this - * yields locks, it will also abandon the current storage engine snapshot. + * Yield lock manager locks and abandon the current storage engine snapshot. */ - void _tryYield(OperationContext*); + void _yield(OperationContext* opCtx); // The entry for the index that is being built. IndexCatalogEntry* _indexCatalogEntry; -- cgit v1.2.1