diff options
author | Jordi Serra Torrens <jordi.serra-torrens@mongodb.com> | 2022-06-17 14:39:34 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-06-17 15:35:53 +0000 |
commit | c3928c511c8aa55a96a823e4cfe7bccb347c1cb2 (patch) | |
tree | c96693dedea179ee72fda679b27433f12958b886 | |
parent | 040ac37b03e9325cdc1de6dbae76172e0bb4a63a (diff) | |
download | mongo-c3928c511c8aa55a96a823e4cfe7bccb347c1cb2.tar.gz |
SERVER-60773 Uassert DDL participant commands are ran as a retryable write
6 files changed, 66 insertions, 92 deletions
diff --git a/src/mongo/db/s/create_collection_coordinator.cpp b/src/mongo/db/s/create_collection_coordinator.cpp index b6df7bce735..1f0ac4ece12 100644 --- a/src/mongo/db/s/create_collection_coordinator.cpp +++ b/src/mongo/db/s/create_collection_coordinator.cpp @@ -507,14 +507,7 @@ ExecutorFuture<void> CreateCollectionCoordinator::_runImpl( ShardingCatalogClient::kMajorityWriteConcern); _updateSession(opCtx); - try { - _createCollectionOnNonPrimaryShards(opCtx, getCurrentSession()); - } catch (const ExceptionFor<ErrorCodes::NotARetryableWriteCommand>&) { - // Older 5.0 binaries don't support running the - // _shardsvrCreateCollectionParticipant command as a retryable write yet. In - // that case, retry without attaching session info. - _createCollectionOnNonPrimaryShards(opCtx, boost::none); - } + _createCollectionOnNonPrimaryShards(opCtx, getCurrentSession()); _commit(opCtx); } @@ -731,7 +724,7 @@ void CreateCollectionCoordinator::_createChunks(OperationContext* opCtx) { } void CreateCollectionCoordinator::_createCollectionOnNonPrimaryShards( - OperationContext* opCtx, const boost::optional<OperationSessionInfo>& osi) { + OperationContext* opCtx, const OperationSessionInfo& osi) { LOGV2_DEBUG(5277905, 2, "Create collection _createCollectionOnNonPrimaryShards", @@ -758,10 +751,9 @@ void CreateCollectionCoordinator::_createCollectionOnNonPrimaryShards( createCollectionParticipantRequest.setIdIndex(idIndex); createCollectionParticipantRequest.setIndexes(indexes); - requests.emplace_back( - chunkShardId, - CommandHelpers::appendMajorityWriteConcern( - createCollectionParticipantRequest.toBSON(osi ? osi->toBSON() : BSONObj()))); + requests.emplace_back(chunkShardId, + CommandHelpers::appendMajorityWriteConcern( + createCollectionParticipantRequest.toBSON(osi.toBSON()))); initializedShards.emplace(chunkShardId); } diff --git a/src/mongo/db/s/create_collection_coordinator.h b/src/mongo/db/s/create_collection_coordinator.h index ac9f9dc7f9e..a6e7d0b9709 100644 --- a/src/mongo/db/s/create_collection_coordinator.h +++ b/src/mongo/db/s/create_collection_coordinator.h @@ -113,7 +113,7 @@ private: * participant shards. */ void _createCollectionOnNonPrimaryShards(OperationContext* opCtx, - const boost::optional<OperationSessionInfo>& osi); + const OperationSessionInfo& osi); /** * Does the following writes: diff --git a/src/mongo/db/s/sharding_ddl_util.cpp b/src/mongo/db/s/sharding_ddl_util.cpp index 75fd5ffa04e..89eb4107f60 100644 --- a/src/mongo/db/s/sharding_ddl_util.cpp +++ b/src/mongo/db/s/sharding_ddl_util.cpp @@ -499,16 +499,8 @@ void sendDropCollectionParticipantCommandToShards(OperationContext* opCtx, const auto cmdObj = CommandHelpers::appendMajorityWriteConcern(dropCollectionParticipant.toBSON({})); - try { - sharding_ddl_util::sendAuthenticatedCommandToShards( - opCtx, nss.db(), cmdObj.addFields(osi.toBSON()), shardIds, executor); - } catch (const ExceptionFor<ErrorCodes::NotARetryableWriteCommand>&) { - // Older 5.0 binaries don't support running the _shardsvrDropCollectionParticipant - // command as a retryable write yet. In that case, retry without attaching session - // info. - sharding_ddl_util::sendAuthenticatedCommandToShards( - opCtx, nss.db(), cmdObj, shardIds, executor); - } + sharding_ddl_util::sendAuthenticatedCommandToShards( + opCtx, nss.db(), cmdObj.addFields(osi.toBSON()), shardIds, executor); } } // namespace sharding_ddl_util diff --git a/src/mongo/db/s/shardsvr_create_collection_participant_command.cpp b/src/mongo/db/s/shardsvr_create_collection_participant_command.cpp index 08ccb14ed30..4157f1145f8 100644 --- a/src/mongo/db/s/shardsvr_create_collection_participant_command.cpp +++ b/src/mongo/db/s/shardsvr_create_collection_participant_command.cpp @@ -80,6 +80,11 @@ public: CommandHelpers::uassertCommandRunWithMajority(Request::kCommandName, opCtx->getWriteConcern()); + const auto txnParticipant = TransactionParticipant::get(opCtx); + uassert(6077300, + str::stream() << Request::kCommandName << " must be run as a retryable write", + txnParticipant); + opCtx->setAlwaysInterruptAtStepDownOrUp_UNSAFE(); MigrationDestinationManager::cloneCollectionIndexesAndOptions( @@ -90,23 +95,15 @@ public: request().getIdIndex(), request().getOptions()}); - // The txnParticipant will only be missing when the command was sent from a coordinator - // running an old 5.0.0 binary that didn't attach a sessionId & txnNumber. - // TODO SERVER-60773: Once 6.0 has branched out, txnParticipant must always exist. Add a - // uassert for that. - auto txnParticipant = TransactionParticipant::get(opCtx); - if (txnParticipant) { - // Since no write that generated a retryable write oplog entry with this sessionId - // and txnNumber happened, we need to make a dummy write so that the session gets - // durably persisted on the oplog. This must be the last operation done on this - // command. - DBDirectClient client(opCtx); - client.update(NamespaceString::kServerConfigurationNamespace.ns(), - BSON("_id" << Request::kCommandName), - BSON("$inc" << BSON("count" << 1)), - true /* upsert */, - false /* multi */); - } + // Since no write that generated a retryable write oplog entry with this sessionId and + // txnNumber happened, we need to make a dummy write so that the session gets durably + // persisted on the oplog. This must be the last operation done on this command. + DBDirectClient client(opCtx); + client.update(NamespaceString::kServerConfigurationNamespace.ns(), + BSON("_id" << Request::kCommandName), + BSON("$inc" << BSON("count" << 1)), + true /* upsert */, + false /* multi */); } private: diff --git a/src/mongo/db/s/shardsvr_drop_collection_participant_command.cpp b/src/mongo/db/s/shardsvr_drop_collection_participant_command.cpp index e1cbf3545a8..31c19139c38 100644 --- a/src/mongo/db/s/shardsvr_drop_collection_participant_command.cpp +++ b/src/mongo/db/s/shardsvr_drop_collection_participant_command.cpp @@ -79,6 +79,11 @@ public: CommandHelpers::uassertCommandRunWithMajority(Request::kCommandName, opCtx->getWriteConcern()); + const auto txnParticipant = TransactionParticipant::get(opCtx); + uassert(6077301, + str::stream() << Request::kCommandName << " must be run as a retryable write", + txnParticipant); + opCtx->setAlwaysInterruptAtStepDownOrUp_UNSAFE(); try { @@ -90,23 +95,16 @@ public: "namespace"_attr = ns()); } - // The txnParticipant will only be missing when the command was sent from a coordinator - // running an old 5.0.0 binary that didn't attach a sessionId & txnNumber. - // TODO SERVER-60773: Once 6.0 has branched out, txnParticipant must always exist. Add a - // uassert for that. - auto txnParticipant = TransactionParticipant::get(opCtx); - if (txnParticipant) { - // Since no write that generated a retryable write oplog entry with this sessionId - // and txnNumber happened, we need to make a dummy write so that the session gets - // durably persisted on the oplog. This must be the last operation done on this - // command. - DBDirectClient client(opCtx); - client.update(NamespaceString::kServerConfigurationNamespace.ns(), - BSON("_id" << Request::kCommandName), - BSON("$inc" << BSON("count" << 1)), - true /* upsert */, - false /* multi */); - } + + // Since no write that generated a retryable write oplog entry with this sessionId and + // txnNumber happened, we need to make a dummy write so that the session gets durably + // persisted on the oplog. This must be the last operation done on this command. + DBDirectClient client(opCtx); + client.update(NamespaceString::kServerConfigurationNamespace.ns(), + BSON("_id" << Request::kCommandName), + BSON("$inc" << BSON("count" << 1)), + true /* upsert */, + false /* multi */); } private: diff --git a/src/mongo/db/s/shardsvr_rename_collection_participant_command.cpp b/src/mongo/db/s/shardsvr_rename_collection_participant_command.cpp index 63427452bf4..16d75a2bfb9 100644 --- a/src/mongo/db/s/shardsvr_rename_collection_participant_command.cpp +++ b/src/mongo/db/s/shardsvr_rename_collection_participant_command.cpp @@ -80,6 +80,11 @@ public: CommandHelpers::uassertCommandRunWithMajority(Request::kCommandName, opCtx->getWriteConcern()); + const auto txnParticipant = TransactionParticipant::get(opCtx); + uassert(6077302, + str::stream() << Request::kCommandName << " must be run as a retryable write", + txnParticipant); + auto const shardingState = ShardingState::get(opCtx); uassertStatusOK(shardingState->canAcceptShardedCommands()); auto const& req = request(); @@ -104,23 +109,15 @@ public: renameCollectionParticipant->getBlockCRUDAndRenameCompletionFuture().get(opCtx); - // The txnParticipant will only be missing when the command was sent from a coordinator - // running an old 5.0.0 binary that didn't attach a sessionId & txnNumber. - // TODO SERVER-60773: Once 6.0 has branched out, txnParticipant must always exist. Add a - // uassert for that. - auto txnParticipant = TransactionParticipant::get(opCtx); - if (txnParticipant) { - // Since no write that generated a retryable write oplog entry with this sessionId - // and txnNumber happened, we need to make a dummy write so that the session gets - // durably persisted on the oplog. This must be the last operation done on this - // command. - DBDirectClient client(opCtx); - client.update(NamespaceString::kServerConfigurationNamespace.ns(), - BSON("_id" << Request::kCommandName), - BSON("$inc" << BSON("count" << 1)), - true /* upsert */, - false /* multi */); - } + // Since no write that generated a retryable write oplog entry with this sessionId and + // txnNumber happened, we need to make a dummy write so that the session gets durably + // persisted on the oplog. This must be the last operation done on this command. + DBDirectClient client(opCtx); + client.update(NamespaceString::kServerConfigurationNamespace.ns(), + BSON("_id" << Request::kCommandName), + BSON("$inc" << BSON("count" << 1)), + true /* upsert */, + false /* multi */); } private: @@ -178,6 +175,11 @@ public: CommandHelpers::uassertCommandRunWithMajority(Request::kCommandName, opCtx->getWriteConcern()); + const auto txnParticipant = TransactionParticipant::get(opCtx); + uassert(6077303, + str::stream() << Request::kCommandName << " must be run as a retryable write", + txnParticipant); + auto const shardingState = ShardingState::get(opCtx); uassertStatusOK(shardingState->canAcceptShardedCommands()); @@ -195,23 +197,16 @@ public: optRenameCollectionParticipant.get()->getUnblockCrudFuture().get(opCtx); } - // The txnParticipant will only be missing when the command was sent from a coordinator - // running an old 5.0.0 binary that didn't attach a sessionId & txnNumber. - // TODO SERVER-60773: Once 6.0 has branched out, txnParticipant must always exist. Add a - // uassert for that. - auto txnParticipant = TransactionParticipant::get(opCtx); - if (txnParticipant) { - // Since no write that generated a retryable write oplog entry with this sessionId - // and txnNumber happened, we need to make a dummy write so that the session gets - // durably persisted on the oplog. This must be the last operation done on this - // command. - DBDirectClient client(opCtx); - client.update(NamespaceString::kServerConfigurationNamespace.ns(), - BSON("_id" << Request::kCommandName), - BSON("$inc" << BSON("count" << 1)), - true /* upsert */, - false /* multi */); - } + // Since no write that generated a retryable write oplog entry with this sessionId + // and txnNumber happened, we need to make a dummy write so that the session gets + // durably persisted on the oplog. This must be the last operation done on this + // command. + DBDirectClient client(opCtx); + client.update(NamespaceString::kServerConfigurationNamespace.ns(), + BSON("_id" << Request::kCommandName), + BSON("$inc" << BSON("count" << 1)), + true /* upsert */, + false /* multi */); } private: |