targetUpdate() excludes findAndModify from the WithoutShardKeyWithId broadcast protocol, but targetDelete() does not: src/mongo/s/query/exec/target_write_op.cpp:670-671 sets isNonTargetedRetryableWriteWithId = isExactId && multipleEndpoints && isRetryableWrite(opCtx) with no !isFindAndModify term, unlike the update path at lines 540-541 and unlike the useTwoPhaseWriteProtocol expression immediately above at line 668. Because write_op_analyzer.cpp:102-103 checks isNonTargetedRetryableWriteWithId before useTwoPhaseWriteProtocol, a retryable findAndModify with remove: true whose filter has an _id equality, on a collection sharded on some other key and spanning more than one shard, is classified kRetryableWriteWithId and broadcast to every chunk-owning shard instead of using the two phase write protocol. After a chunk migration copies the session history, both the donor and the recipient hold the history for that statement, so retrying it makes two shards each return a successful findAndModify reply for the same op; unlike batch write replies these are recorded rather than summed, so the second one trips tassert(11182206, "Expected no previous findAndModify result for op") at src/mongo/s/write_ops/unified_write_executor/write_batch_response_processor.cpp:677 and the command fails with Location11182206 instead of returning the retried result. This is UWE-only and does not affect legacy BatchWriteExec: with the feature flag off, findAndModify takes its own path in cluster_find_and_modify_cmd.cpp via write_without_shard_key::useTwoPhaseProtocol() and never reaches targetDelete(), and WriteOp::targetWrites() never sees a findAndModify at all, so the missing term was dead code until findAndModify was routed through UWE at cluster_find_and_modify_cmd.cpp:742. It reproduces deterministically on master with UWE on, does not reproduce with featureFlagUnifiedWriteExecutor: false against the same unfixed binary, and adding && !isFindAndModify at line 670 fixes it.
Retryable findAndModify remove by _id is broadcast to all shards and tasserts on retry after chunk migration
- Assignee:
-
Mickey Winters
- Reporter:
-
Mickey Winters
- Votes:
-
0 Vote for this issue - Watchers:
-
4 Start watching this issue
- Created:
- Updated:
- Resolved: