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/dbhelpers.cpp | |
parent | 46b4b3d8f03e3dfc3ca2ae344bf7848732e986c3 (diff) | |
download | mongo-c15e8ae74071482d69179c7e5e5e6bdc882d2beb.tar.gz |
SERVER-45626: Introduce AutoGetOplog for consistent oplog locking rules
Diffstat (limited to 'src/mongo/db/dbhelpers.cpp')
-rw-r--r-- | src/mongo/db/dbhelpers.cpp | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/src/mongo/db/dbhelpers.cpp b/src/mongo/db/dbhelpers.cpp index 47d13e8d46b..ef6c35ffe8b 100644 --- a/src/mongo/db/dbhelpers.cpp +++ b/src/mongo/db/dbhelpers.cpp @@ -48,11 +48,6 @@ #include "mongo/db/query/get_executor.h" #include "mongo/db/query/internal_plans.h" #include "mongo/db/query/query_planner.h" -#include "mongo/db/repl/repl_client_info.h" -#include "mongo/db/repl/replication_coordinator.h" -#include "mongo/db/service_context.h" -#include "mongo/db/write_concern.h" -#include "mongo/db/write_concern_options.h" #include "mongo/util/scopeguard.h" #include "mongo/util/str.h" @@ -172,10 +167,28 @@ RecordId Helpers::findById(OperationContext* opCtx, return catalog->getEntry(desc)->accessMethod()->findSingle(opCtx, idquery["_id"].wrap()); } +// Acquires necessary locks to read the collection with the given namespace. If this is an oplog +// read, use AutoGetOplog for simplified locking. +Collection* getCollectionForRead(OperationContext* opCtx, + const NamespaceString& ns, + boost::optional<AutoGetCollectionForReadCommand>& autoColl, + boost::optional<AutoGetOplog>& autoOplog) { + if (ns.isOplog()) { + // Simplify locking rules for oplog collection. + autoOplog.emplace(opCtx, OplogAccessMode::kRead); + return autoOplog->getCollection(); + } else { + autoColl.emplace(opCtx, NamespaceString(ns)); + return autoColl->getCollection(); + } +} + bool Helpers::getSingleton(OperationContext* opCtx, const char* ns, BSONObj& result) { - AutoGetCollectionForReadCommand ctx(opCtx, NamespaceString(ns)); - auto exec = - InternalPlanner::collectionScan(opCtx, ns, ctx.getCollection(), PlanExecutor::NO_YIELD); + boost::optional<AutoGetCollectionForReadCommand> autoColl; + boost::optional<AutoGetOplog> autoOplog; + auto collection = getCollectionForRead(opCtx, NamespaceString(ns), autoColl, autoOplog); + + auto exec = InternalPlanner::collectionScan(opCtx, ns, collection, PlanExecutor::NO_YIELD); PlanExecutor::ExecState state = exec->getNext(&result, nullptr); CurOp::get(opCtx)->done(); @@ -192,9 +205,12 @@ bool Helpers::getSingleton(OperationContext* opCtx, const char* ns, BSONObj& res } bool Helpers::getLast(OperationContext* opCtx, const char* ns, BSONObj& result) { - AutoGetCollectionForReadCommand autoColl(opCtx, NamespaceString(ns)); + boost::optional<AutoGetCollectionForReadCommand> autoColl; + boost::optional<AutoGetOplog> autoOplog; + auto collection = getCollectionForRead(opCtx, NamespaceString(ns), autoColl, autoOplog); + auto exec = InternalPlanner::collectionScan( - opCtx, ns, autoColl.getCollection(), PlanExecutor::NO_YIELD, InternalPlanner::BACKWARD); + opCtx, ns, collection, PlanExecutor::NO_YIELD, InternalPlanner::BACKWARD); PlanExecutor::ExecState state = exec->getNext(&result, nullptr); // Non-yielding collection scans from InternalPlanner will never error. |