diff options
author | Lingzhi Deng <lingzhi.deng@mongodb.com> | 2020-03-03 10:46:39 -0500 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-03-13 17:21:07 +0000 |
commit | c15e8ae74071482d69179c7e5e5e6bdc882d2beb (patch) | |
tree | a17f28ebb0e53c69f2b1c07f6e4d41dedf78f5fe /src/mongo/db/catalog_raii.cpp | |
parent | 46b4b3d8f03e3dfc3ca2ae344bf7848732e986c3 (diff) | |
download | mongo-c15e8ae74071482d69179c7e5e5e6bdc882d2beb.tar.gz |
SERVER-45626: Introduce AutoGetOplog for consistent oplog locking rules
Diffstat (limited to 'src/mongo/db/catalog_raii.cpp')
-rw-r--r-- | src/mongo/db/catalog_raii.cpp | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/src/mongo/db/catalog_raii.cpp b/src/mongo/db/catalog_raii.cpp index 156727191dd..aacce83a287 100644 --- a/src/mongo/db/catalog_raii.cpp +++ b/src/mongo/db/catalog_raii.cpp @@ -182,4 +182,37 @@ ReadSourceScope::~ReadSourceScope() { } } +AutoGetOplog::AutoGetOplog(OperationContext* opCtx, OplogAccessMode mode, Date_t deadline) + : _shouldNotConflictWithSecondaryBatchApplicationBlock(opCtx->lockState()) { + if (mode == OplogAccessMode::kLogOp) { + // Invariant that global lock is already held for kLogOp mode. + invariant(opCtx->lockState()->isWriteLocked()); + } else { + _globalLock.emplace(opCtx, + mode == OplogAccessMode::kRead ? MODE_IS : MODE_IX, + deadline, + Lock::InterruptBehavior::kThrow); + } + + // Obtain database and collection intent locks for non-document-locking storage engines. + if (!opCtx->getServiceContext()->getStorageEngine()->supportsDocLocking()) { + auto lockMode = (mode == OplogAccessMode::kRead) ? MODE_IS : MODE_IX; + + // If mode is kLogOp, only acquire the database lock if it is not already held. + if (mode != OplogAccessMode::kLogOp || + !opCtx->lockState()->isDbLockedForMode(NamespaceString::kLocalDb, lockMode)) { + _dbWriteLock.emplace(opCtx, NamespaceString::kLocalDb, lockMode, deadline); + } + + // If mode is kLogOp, only acquire the collection lock if it is not already held. + if (mode != OplogAccessMode::kLogOp || + !opCtx->lockState()->isCollectionLockedForMode(NamespaceString::kRsOplogNamespace, + lockMode)) { + _collWriteLock.emplace(opCtx, NamespaceString::kRsOplogNamespace, lockMode, deadline); + } + } + _oplogInfo = repl::LocalOplogInfo::get(opCtx); + _oplog = _oplogInfo->getCollection(); +} + } // namespace mongo |