-
Type:
Improvement
-
Resolution: Unresolved
-
Priority:
Major - P3
-
None
-
Affects Version/s: None
-
Component/s: None
-
None
-
Query Execution
-
None
-
None
-
None
-
None
-
None
-
None
-
None
Query-memory load shedding (SERVER-130333) is supposed to be restricted to read operations, but the design of this restriction does not property protect Time Series writes
The gap: some writes issue reads on the write path via DBDirectClient, which dispatch through those same command run() entry points and therefore get marked eligible on the enclosing write's opCtx. The motivating case is time-series inserts, which reopen an existing bucket to append to (for column-compression density) by running a findOne / index-hinted $match aggregation via DBDirectClient (bucket_catalog_internal.cpp: reopenFetchedBucket, reopenQueriedBucket). If such a read were shed, the insert could fall back to opening a new bucket, increasing write amplification and memory pressure — the opposite of the feature's intent.
Current behavior (why the practical risk is low today)
The reopening reads have no blocking stages, so they create no OperationMemoryUsageTracker / accumulate zero tracked bytes. The shed decision short-circuits at the "no tracker" and opTrackedBytes <= 0 checks before the probability roll (and before the high-mark p=1 rule inside shedProbability), so these reads are never shed at any pressure. There is also no correctness exposure: the read runs during target selection, before any bucket write, and the insert is a retryable write — so the "shed after a partial non-idempotent write" hazard (covered separately by the write-intent-lock exemption) does not apply.
Proposed change
Make "internal nested reads are not shedding candidates" a guaranteed invariant rather than an accident of their zero-tracked-memory profile: skip markOperationQueryMemorySheddingEligible() when opCtx->getClient()->isInDirectClient(). ThiBDirectClient}} reads issued inside a largeroperation, protecting against a future internal read that does buffer memory (e.g. a reworked reopening path, or an internal $group/$sort).
This is orthogonal to router→shard subqueries (h as remote commands, so shard- and router-sidework arrives as top-level, non-direct-client operations and remains sheddable.
Scope / testing
- Guard eligibility marking on !isInDirectClient() (single choke point in the eligibility helper, or per command mark-site).
- Unit/integration test: a memory-tracked DBDirectClient read under simulated pressure (pressure-override failpoint) is
not shed. - Update README.query_memory_load_shedding.md: note the no-tracker / zero-tracked-bytes gate is the primary protection,
with the direct-client guard as a durable backsn-interaction note. - Confirm (or file follow-up for) the time-series insert path treating a retriable read failure as retry, not new-bucket
fallback.
Priority
Low — hardening / defense-in-depth. No active bug in current code; the change future-proofs the eligibility boundary and lets us state categorically that write-path internal reads are never shed.
- is related to
-
SERVER-130333 Probabilistic query memory load shedding
-
- Closed
-