From 30fd6783cdd01d98e0b1ee97021d0f459ccebf5f Mon Sep 17 00:00:00 2001 From: Abuhaithem Date: Sun, 28 Jun 2026 12:10:20 +0300 Subject: [PATCH] fix(sharding): enqueue delete for deferred updates moving out of migrating chunk If a deferred transaction update moves a document out of a migrating chunk and the document is subsequently deleted before `_processDeferredXferMods` runs, the destination shard misses the deletion, leaving an orphaned document. This commit updates `_processDeferredXferMods` to model a delete if the document is no longer found and its pre-image was in the chunk. --- src/mongo/db/s/migration_chunk_cloner_source.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/mongo/db/s/migration_chunk_cloner_source.cpp b/src/mongo/db/s/migration_chunk_cloner_source.cpp index b35f1d732efb8..6390d94467aa1 100644 --- a/src/mongo/db/s/migration_chunk_cloner_source.cpp +++ b/src/mongo/db/s/migration_chunk_cloner_source.cpp @@ -905,13 +905,23 @@ void MigrationChunkClonerSource::_processDeferredXferMods(OperationContext* opCt deferredReloadOrDeletePreImageDocKeys.swap(_deferredReloadOrDeletePreImageDocKeys); } + auto const& minKey = _args.getMin().value(); + auto const& maxKey = _args.getMax().value(); + for (const auto& preImageDocKey : deferredReloadOrDeletePreImageDocKeys) { auto idElement = preImageDocKey["_id"]; BSONObj newerVersionDoc; if (!Helpers::findById(opCtx, this->nss(), BSON("_id" << idElement), newerVersionDoc)) { // If the document can no longer be found, this means that another later op must have - // deleted it. That delete would have been captured by the xferMods so nothing else to - // do here. + // deleted it. If the document was moved out of the chunk by this transaction and then + // deleted, the later delete would not have been captured by the xferMods. We must + // explicitly model a delete if the pre-image was in the chunk. + auto preImageShardKeyValues = + _shardKeyPattern.extractShardKeyFromDocumentKey(preImageDocKey); + + if (isKeyInRange(preImageShardKeyValues, minKey, maxKey)) { + _addToTransferModsQueue(idElement.wrap(), 'd', {}); + } continue; }