Skip to content

GC: Replayer::Replay does not yield, occupying the shard worker thread for non-active-branch manifests #456

Description

@liunyl

Summary

Replayer::Replay (src/replayer.cpp) reconstructs a partition's page mapping from a manifest by deserializing the base snapshot and then replaying every incremental log record in a tight while (true) loop. That loop has no cooperative yield, and because the manifest is already read into an in-memory buffer before replay, the whole reconstruction is one uninterrupted synchronous CPU segment.

In module mode the shard worker thread also drives the TxProcessor on the same core, so a long non-yielding segment in Replay stalls foreground serving for its entire duration (tens of ms for a large manifest).

Where it bites

GC's AugmentRetainedFilesFromBranchManifests -> ProcessOneManifest -> Replayer::Replay, run once per file-GC pass (i.e. after each compaction). Note:

So the remaining gap is the non-active-branch / archive path: those branches have no trustworthy in-memory mapping, so GC must replay their disk manifests — and that replay does not yield.

Proposed fix

Add a cooperative yield inside the replay record loop (e.g. MaybeYieldForCompaction() / ThdTask()->YieldToLowPQ() every N replayed records) so a single manifest replay cannot hold the worker thread past the cooperative yield budget. Keep it cheap (a counter + periodic check) since Replay is also used on the recovery/startup path.

Notes

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions