diff options
author | Jason Zhang <jason.zhang@mongodb.com> | 2021-04-26 14:45:41 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-04-29 17:50:57 +0000 |
commit | 51bef6c2d9d035afed3735ea107d1e7b58392d93 (patch) | |
tree | 9ec44bad7e34a903f4719a68d4388e87470fa3ad /src/mongo/db | |
parent | 40ac62ae387cff401b4d067890083fd5f4586cf6 (diff) | |
download | mongo-51bef6c2d9d035afed3735ea107d1e7b58392d93.tar.gz |
SERVER-56188 Nested applyOps can hold onto global X lock while blocking on migration commit/abort
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/repl/apply_ops.cpp | 78 |
1 files changed, 20 insertions, 58 deletions
diff --git a/src/mongo/db/repl/apply_ops.cpp b/src/mongo/db/repl/apply_ops.cpp index e21fe107a44..840cd23db3b 100644 --- a/src/mongo/db/repl/apply_ops.cpp +++ b/src/mongo/db/repl/apply_ops.cpp @@ -51,7 +51,6 @@ #include "mongo/db/operation_context.h" #include "mongo/db/query/collation/collation_spec.h" #include "mongo/db/repl/replication_coordinator.h" -#include "mongo/db/repl/tenant_migration_conflict_info.h" #include "mongo/db/service_context.h" #include "mongo/db/session_catalog_mongod.h" #include "mongo/db/transaction_participant.h" @@ -67,7 +66,7 @@ constexpr StringData ApplyOps::kOplogApplicationModeFieldName; namespace { -// If enabled, causes loop in _applyOpsWithCommandInfo() to hang after applying current operation. +// If enabled, causes loop in _applyOps() to hang after applying current operation. MONGO_FAIL_POINT_DEFINE(applyOpsPauseBetweenOperations); /** @@ -98,12 +97,12 @@ bool _parseAreOpsCrudOnly(const BSONObj& applyOpCmd) { return true; } -Status _applyOpsWithCommandInfo(OperationContext* opCtx, - const ApplyOpsCommandInfo& info, - repl::OplogApplication::Mode oplogApplicationMode, - BSONObjBuilder* result, - int* numApplied, - BSONArrayBuilder* opsBuilder) { +Status _applyOps(OperationContext* opCtx, + const ApplyOpsCommandInfo& info, + repl::OplogApplication::Mode oplogApplicationMode, + BSONObjBuilder* result, + int* numApplied, + BSONArrayBuilder* opsBuilder) { const auto& ops = info.getOperations(); // apply *numApplied = 0; @@ -384,11 +383,11 @@ Status applyApplyOpsOplogEntry(OperationContext* opCtx, &resultWeDontCareAbout); } -Status _applyOps(OperationContext* opCtx, - const std::string& dbName, - const BSONObj& applyOpCmd, - repl::OplogApplication::Mode oplogApplicationMode, - BSONObjBuilder* result) { +Status applyOps(OperationContext* opCtx, + const std::string& dbName, + const BSONObj& applyOpCmd, + repl::OplogApplication::Mode oplogApplicationMode, + BSONObjBuilder* result) { auto info = ApplyOpsCommandInfo::parse(applyOpCmd); int numApplied = 0; @@ -426,8 +425,7 @@ Status _applyOps(OperationContext* opCtx, } if (!info.isAtomic()) { - return _applyOpsWithCommandInfo( - opCtx, info, oplogApplicationMode, result, &numApplied, nullptr); + return _applyOps(opCtx, info, oplogApplicationMode, result, &numApplied, nullptr); } // Perform write ops atomically @@ -445,12 +443,12 @@ Status _applyOps(OperationContext* opCtx, { // Suppress replication for atomic operations until end of applyOps. repl::UnreplicatedWritesBlock uwb(opCtx); - uassertStatusOK(_applyOpsWithCommandInfo(opCtx, - info, - oplogApplicationMode, - &intermediateResult, - &numApplied, - opsBuilder.get())); + uassertStatusOK(_applyOps(opCtx, + info, + oplogApplicationMode, + &intermediateResult, + &numApplied, + opsBuilder.get())); } // Generate oplog entry for all atomic ops collectively. if (opCtx->writesAreReplicated()) { @@ -485,8 +483,7 @@ Status _applyOps(OperationContext* opCtx, } catch (const DBException& ex) { if (ex.code() == ErrorCodes::AtomicityFailure) { // Retry in non-atomic mode. - return _applyOpsWithCommandInfo( - opCtx, info, oplogApplicationMode, result, &numApplied, nullptr); + return _applyOps(opCtx, info, oplogApplicationMode, result, &numApplied, nullptr); } BSONArrayBuilder ab; ++numApplied; @@ -503,41 +500,6 @@ Status _applyOps(OperationContext* opCtx, return Status::OK(); } -Status applyOps(OperationContext* opCtx, - const std::string& dbName, - const BSONObj& applyOpCmd, - repl::OplogApplication::Mode oplogApplicationMode, - BSONObjBuilder* result) { - auto status = _applyOps(opCtx, dbName, applyOpCmd, oplogApplicationMode, result); - if (status == ErrorCodes::TenantMigrationConflict) { - auto migrationConflictInfo = status.template extraInfo<TenantMigrationConflictInfo>(); - auto mtab = migrationConflictInfo->getTenantMigrationAccessBlocker(); - auto migrationStatus = - mtab->waitUntilCommittedOrAborted(opCtx, migrationConflictInfo->getOperationType()); - mtab->recordTenantMigrationError(migrationStatus); - - auto response = result->asTempObj(); - - auto numApplied = response.getIntField("applied"); - BSONArrayBuilder resultsBuilder; - BSONObjIterator it(response.getObjectField("results")); - while (it.more()) { - BSONElement e = it.next(); - resultsBuilder.append(e.Bool()); - } - - result->resetToEmpty(); - result->append("applied", numApplied); - result->append("code", migrationStatus.code()); - result->append("codeName", ErrorCodes::errorString(migrationStatus.code())); - result->append("errmsg", migrationStatus.reason()); - result->append("results", resultsBuilder.arr()); - - return migrationStatus; - } - return status; -} - // static std::vector<OplogEntry> ApplyOps::extractOperations(const OplogEntry& applyOpsOplogEntry) { std::vector<OplogEntry> result; |