ExportXMLWordPrintableJSON

    • Type: Investigation
    • Resolution: Won't Fix
    • Priority: Major - P3
    • No version
    • Affects Version/s: None
    • Component/s: None
    • None
    • Not Needed
    • Developer Tools

      Original Downstream Change Summary

      Downstream Changes Summary

      Project context
      ---------------
      $_internalSearchIdLookup is the internal stage that resolves $search/$vectorSearch result
      documents by _id after the mongot remote query returns matching ids. Historically it always ran
      through a per-lookup routed aggregation (local read). With featureFlagSearchOptimizedIdLookup on
      and no view pipeline, the stage now uses an SBE point-read as primary (search always runs local;
      sharding-filter drops orphans), falling back to the routed aggregation executor when SBE declines
      (e.g. an object _id the slot binder cannot encode). A view pipeline always forces the aggregation
      path. Change stream updateLookup uses the analogous primary-with-fallback chain described in
      SERVER-129513/129514/129515 (SBE for collection streams, Express for database/cluster-wide
      streams, aggregation fallback).

      What this ticket adds
      ---------------------
      1. A brand-new serverStatus section, metrics.search.idLookup, mirroring the updateLookup per-
      engine cells for the idLookup stage:

      • {sbe,aggregation}.found / notFound (counters): the lookup ran on this engine and did / did
        not resolve the _id.
        - {sbe,aggregation}

        .notHandled (counter): the engine declined; the fallback serves it. Not an
        error.

      • {sbe,aggregation}

        .latencyMicros (histogram, microseconds): wall time of a single lookup
        attempt; recorded only for executed (found/notFound) lookups.
        The sbe cells record only when the optimization flag is on; aggregation records in both modes.
        2. New enrich-batch counters (engine-independent, one per consumer):

      • metrics.changeStreams.updateLookup.enrichBatchesStarted
      • metrics.search.idLookup.enrichBatchesStarted
        One increment per enrichment SUB-BATCH opened by BatchedEnrichmentStage - the resource-scope
        window, not the client getMore/fill batch (one fill window may open several sub-batches).
        Counted before beginBatch(), so failed batch openings are included. Purpose: a direct
        invariance signal for the batching knobs (maxInputEvents / maxInputBytes / maxOutputBytes) -
        if a knob changes, this counter must move.

      All metrics are also exported through OpenTelemetry under the mongodb.serverStatus.metrics.*
      prefix, appear zeroed in serverStatus from startup regardless of flag state, and are per mongod
      process. No new commands, options, or wire-protocol changes; no change to lookup results.
      Backported to v9.0 (BACKPORT-29761).

      Description of Linked Ticket

      Overview

      Change-stream updateLookup and $_internalSearchIdLookup share the
      SingleDocumentLookupExecutor / BatchedEnrichmentStage enrichment abstraction. This work extends
      the per-engine lookup metrics to $_internalSearchIdLookup, adds per-consumer enrich-batch
      counters, and broadens test coverage across the dimensions the shared module serves: _id shapes
      (including fallback-handled declines), clustered collections, collation, sharding and placement
      changes, concurrent DDL, batching knobs, and interrupts.

      Observability

      • Per-engine outcome and latency metrics for search idLookup under search.idLookup.sbe and
        search.idLookup.aggregation (found, notFound, notHandled, latencyMicros),
        wired in buildIdLookupExecutor().
      • Per-consumer enrich-window counters changeStreams.updateLookup.enrichBatchesStarted and
        search.idLookup.enrichBatchesStarted, making batching knobs directly verifiable.

      Test coverage

      $_internalSearchIdLookup

      • Coverage reworked around a shared mock-mongot util: _id shape matrix, unsupported shapes
        (regex/array) asserted to resolve cleanly through the fallback executor, mixed-shape batches
        with per-engine attribution, view-pipeline fallback, DDL between getMores, killOp mid-batch.
      • Batching-knob invariance verified via the new enrich-batch counters.
      • Sharding/DDL concurrency: shard-key strategy matrix, migration orphan filtering,
        parked-cursor-across-migration, view-backed orphan case.

      Change-stream updateLookup

      • Engine-attribution metrics tests across clustered/collation matrices, including mixed
        scalar/compound _id batches.
      • Batching-knob verification with engine-based eligibility.
      • DDL timing: update_lookup_before_ddl.js rework plus a new noPassthrough mid-batch file using
        the hangBeforeChangeStreamUpdateLookup fail point (mid-batch cached-acquisition staleness,
        killOp mid-batch).
      • TooManyMatchingDocuments regression test for the sharded scatter-gather case.
      • New shared helpers: expectedUpdateLookupEngine(), readUpdateLookupDelta(),
        assertChangeStreamEventsEqUnordered() / assertChangeStreamEventsEqWithDeploymentAwareness().

      Unit tests

      • SbeSingleDocumentLookupExecutor: decline paths for unsupported _id shapes (non-scalar _id
        support tracked as SERVER-134080), cached-plan survival across mid-sequence declines,
        accept-side allow-list, shard filtering, plan invalidation, lifecycle.
      • Stats recorders: all factories plus cross-consumer cell independence, enrich-batch counters,
        and throw-integrity for the aggregation executor.

      Observations recorded for follow-up

      • The view-backed local-read executor appears not to request shard filtering (orphan returned);
        pinned as a KNOWN ISSUE assertion in the sharded DDL-concurrency test.
      • The shard filter appears stale across a parked cursor even under SBE; pinned the same way.

      Related

            Assignee:
            Unassigned
            Reporter:
            Backlog - Core Eng Program Management Team
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: