Fix race between MovePrimaryCommand and MoveCollectionCommand in change-stream FSM sharding tests

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Fixed
    • Priority: Major - P3
    • 9.1.0-rc0, 9.0.0-rc2
    • Affects Version/s: None
    • Component/s: None
    • None
    • Query Execution
    • Fully Compatible
    • ALL
    • QE 2026-08-03
    • 200
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      Overview

      Fix a race in the change-stream FSM sharding test harness between two independent writer threads' MovePrimaryCommand and MoveCollectionCommand, which causes an expected reshardCollection change-stream notification to never be emitted – hanging the reader thread and timing out the test. Root-caused from BF-44759.

      Root Cause

      test_coll_fsm and test_coll_fsm_2 are modeled by two independent writer threads that deliberately share one database (test_cs), to exercise database-scoped change-stream merging. An untracked collection has no independent placement record – its location is wherever config.databases.primary points. MoveCollectionCommand's target-shard pick (read current primary, choose a different shard) can be invalidated by the other writer's concurrent MovePrimaryCommand landing on that exact target in the window between the read and when the server actually processes the moveCollection call. The resharding coordinator then correctly treats the operation as redundant and skips the change-stream notification for it.

      Confirmed server-side: movePrimary takes DDL lock mode X on the database; reshardCollection takes mode IX on the same resource – already mutually exclusive at the DDL-lock level. Only the writers' client-side shard picks are unsynchronized to that boundary.

      Scope of Work

      • jstests/libs/util/change_stream/change_stream_connector.js – add Connector.acquireLock/releaseLock, a findAndModify-based cross-writer mutex in the existing control-database pattern
      • jstests/libs/util/change_stream/change_stream_commands.js – wrap MovePrimaryCommand.execute() (always) and MoveCollectionCommand.execute() (only while !collectionCtx.isUnsplittable) in the lock

            Assignee:
            Denis Grebennicov
            Reporter:
            Denis Grebennicov
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: