-
Type:
Task
-
Resolution: Won't Fix
-
Priority:
Major - P3
-
None
-
Affects Version/s: None
-
Component/s: None
-
None
-
Query Execution
-
None
-
None
-
None
-
None
-
None
-
None
-
None
The adaptive write-conflict retry cap (SERVER-126462) never fires for traffic routed through mongos, so a sharded cluster gets neither write-conflict shedding nor the baseBackoffMS hint added by SERVER-132357.
checkWriteConflictStorm returns early at src/mongo/db/query/write_conflict_storm.cpp:96-98 unless the client is an external user connection, and every mongos-to-shard connection sets internalClient unconditionally (src/mongo/s/mongos_main.cpp:712 -> src/mongo/db/wire_version.cpp:34-49, called from every egress handshake builder). The cap therefore only sheds on a direct user connection to a mongod.
Three separate changes are needed.
1. Make the shard-side cap see router-forwarded user writes
Treat isExternalClientOnRouter(opCtx) as an external connection in write_conflict_storm.cpp:96-98, mirroring the existing use at src/mongo/db/service_entry_point_shard_role.cpp:1213-1216:
auto isInternal = \_isInternalClient\(\) && \!isExternalClientOnRouter\(opCtx\);
The propagation already exists: src/mongo/s/client_metadata_propagation_egress_hook.cpp:85-91 stamps the field on egress, src/mongo/rpc/metadata.cpp:219-221 parses it into the decoration in {{src/mongo/db/stats/external_client_on_router.
{h,cpp}}}. It is gated on gFeatureFlagExternalClientOnRouter, so this needs an FCV story and a decision on routers that do not stamp the field.
2. Stop mongos demoting the shed to a per-operation writeError
BulkWriteOp::noteErrorForRemainingWrites (src/mongo/s/write_ops/bulk_write_exec.cpp:906-923) and src/mongo/s/write_ops/batch_write_op.cpp:857 turn a shard's ok:0 into a writeErrors entry with a top-level ok:1. src/mongo/s/commands/strategy.cpp:441-453 then sees an OK status and attaches no error labels. That defeats the rethrow at src/mongo/db/query/write_ops/write_ops_exec.cpp:479-484, which exists specifically to keep the shed at command level so label attachment fires.
The baseBackoffMS value itself does survive this framing, because it rides on the Status as a WriteConflictBackoffInfo and per-operation replies serialize extra info (src/mongo/db/commands/query_cmd/bulk_write_parser.cpp:125-127). This item is about the labels, not the value.
3. Give the client a retryable signal on mongos
RetryableWriteError is suppressed for mongos by the !_isMongos check at src/mongo/db/error_labels.cpp:106-110, and the RetryableError branch at :210-212 is dead behind isOperationIdempotent() (:173-177, SERVER-108898). Without one of those labels a driver will not retry and will not read baseBackoffMS. Either resolve SERVER-108898 or add router-side handling.
Test coverage
The write-conflict tasks are absent from the sharded task list (&availability-tasks-sharded-atlas, dsi evergreen/system_perf/master/variants.yml:1666-1682). The existing pre_task also applies internalQueryWriteConflictRetryLimitMax -- a mongod query knob (src/mongo/db/query/query_execution_knobs.idl:1215) -- to the mongos URI, where it never reaches the shards.
- is related to
-
SERVER-132357 Attach retryAfterMs for the WriteConflictRetryLimitExceeded error based on the load
-
- Closed
-