diff options
author | Esha Maharishi <esha.maharishi@mongodb.com> | 2018-12-10 16:14:59 -0500 |
---|---|---|
committer | Esha Maharishi <esha.maharishi@mongodb.com> | 2018-12-11 18:42:05 -0500 |
commit | f948fbcf86d104d70889d7d6a1caa83b4d78a6a8 (patch) | |
tree | 9765fb007e9bd29e12cdd0e62cea6264625e696b /src/mongo/s/transaction_router.cpp | |
parent | 4f5cb3722dce75ceb77cd705c683f2bbf25b9048 (diff) | |
download | mongo-f948fbcf86d104d70889d7d6a1caa83b4d78a6a8.tar.gz |
SERVER-36853 Coordinator should resume coordinating commit for unfinished transactions on stepup
Diffstat (limited to 'src/mongo/s/transaction_router.cpp')
-rw-r--r-- | src/mongo/s/transaction_router.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/src/mongo/s/transaction_router.cpp b/src/mongo/s/transaction_router.cpp index 3af5fe824ff..44658b473c3 100644 --- a/src/mongo/s/transaction_router.cpp +++ b/src/mongo/s/transaction_router.cpp @@ -47,11 +47,16 @@ #include "mongo/s/cluster_commands_helpers.h" #include "mongo/s/grid.h" #include "mongo/util/assert_util.h" +#include "mongo/util/fail_point_service.h" #include "mongo/util/log.h" namespace mongo { namespace { +// TODO (SERVER-37886): Remove this failpoint once failover can be tested on coordinators that +// have a local participant. +MONGO_FAIL_POINT_DEFINE(sendCoordinateCommitToConfigServer); + const char kCoordinatorField[] = "coordinator"; const char kReadConcernLevelSnapshotName[] = "snapshot"; @@ -566,6 +571,38 @@ Shard::CommandResponse TransactionRouter::_commitMultiShardTransaction(Operation auto coordinatorShard = uassertStatusOK(Grid::get(opCtx)->shardRegistry()->getShard(opCtx, *_coordinatorId)); + if (MONGO_FAIL_POINT(sendCoordinateCommitToConfigServer)) { + LOG(0) << "Sending coordinateCommit for transaction " << *opCtx->getTxnNumber() + << " on session " << opCtx->getLogicalSessionId()->toBSON() + << " to config server rather than actual coordinator because failpoint is active"; + + coordinatorShard = Grid::get(opCtx)->shardRegistry()->getConfigShard(); + + // Send a fake transaction statement to the config server primary so that the config server + // primary sets up state in memory to receive coordinateCommit. + auto cmdResponse = coordinatorShard->runCommandWithFixedRetryAttempts( + opCtx, + ReadPreferenceSetting{ReadPreference::PrimaryOnly}, + "dummy", + coordinatorIter->second.attachTxnFieldsIfNeeded(BSON("distinct" + << "dummy" + << "key" + << "dummy"), + true), + Shard::RetryPolicy::kIdempotent); + uassertStatusOK(Shard::CommandResponse::getEffectiveStatus(cmdResponse)); + + // Abort the fake transaction on the config server to release the actual transaction's + // resources. + cmdResponse = coordinatorShard->runCommandWithFixedRetryAttempts( + opCtx, + ReadPreferenceSetting{ReadPreference::PrimaryOnly}, + "admin", + coordinatorIter->second.attachTxnFieldsIfNeeded(BSON("abortTransaction" << 1), false), + Shard::RetryPolicy::kIdempotent); + uassertStatusOK(Shard::CommandResponse::getEffectiveStatus(cmdResponse)); + } + CoordinateCommitTransaction coordinateCommitCmd; coordinateCommitCmd.setDbName("admin"); coordinateCommitCmd.setParticipants(participantList); |