summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenety Goh <benety@mongodb.com>2019-10-23 14:24:40 +0000
committerevergreen <evergreen@mongodb.com>2019-10-23 14:24:40 +0000
commit1eb3e9a9b1b9792e04351ab6fd72438071560975 (patch)
treee4b48e5f5035b1817fe0dcfa5a77d4e3c8444f02
parent20ca77a7181ad9629b91eae1884664cfaa4e6941 (diff)
downloadmongo-1eb3e9a9b1b9792e04351ab6fd72438071560975.tar.gz
SERVER-44121 IndexBuildInterceptor::drainWritesIntoIndex() yields locks only when directly by drain yield policy
-rw-r--r--src/mongo/db/index/index_build_interceptor.cpp21
-rw-r--r--src/mongo/db/index/index_build_interceptor.h5
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;