Skip to content

gc: Support excluding GC barriers and global GC barriers when retrieving GC states#10669

Open
MyonKeminta wants to merge 9 commits into
tikv:masterfrom
MyonKeminta:m/exclude-gc-barriers
Open

gc: Support excluding GC barriers and global GC barriers when retrieving GC states#10669
MyonKeminta wants to merge 9 commits into
tikv:masterfrom
MyonKeminta:m/exclude-gc-barriers

Conversation

@MyonKeminta
Copy link
Copy Markdown
Contributor

@MyonKeminta MyonKeminta commented May 12, 2026

What problem does this PR solve?

Issue Number: Ref #10659

What is changed and how does it work?

Makes GC states API `GetGCState` and `GetAllKeyspacesGCStates` supportexcluding GC barriers and global GC barriers.

As in most cases the caller don't really need these information, ignoring them could reduce the etcd read
pressure. This is also the prerequisite of supporting GC state caching -- we plan to cache all GC safe points
and txn safe points, but not including GC barriers to keep the memory consumption under control.

The protocol doesn't enable these options by default (otherwise old clients may lost GC barriers information
silently). But the new golang PD client enables them by default, and the updated PD client API can detect the
error.

Check List

Tests

  • Unit test
  • Integration test

Code changes

-

Side effects

  • Increased code complexity

Related changes

-

Release note

None.

Summary by CodeRabbit

  • New Features

    • GC State API now accepts options to fetch GC state with or without barrier data (exclusion-by-default).
  • Refactor

    • GC barrier fields made internal; accessors added to indicate presence or return an error when absent.
    • Manager and server APIs updated to support barrier-exclusion views and separate result handling.
  • Tests

    • Added/updated tests for barrier inclusion/exclusion, accessor behavior, and concurrency isolation of option variants.
  • Chores

    • Updated module dependency versions.

Review Change Stack

Signed-off-by: MyonKeminta <MyonKeminta@users.noreply.github.com>
Signed-off-by: MyonKeminta <MyonKeminta@users.noreply.github.com>
Signed-off-by: MyonKeminta <MyonKeminta@users.noreply.github.com>
@ti-chi-bot ti-chi-bot Bot added release-note-none Denotes a PR that doesn't merit a release note. dco-signoff: yes Indicates the PR's author has signed the dco. labels May 12, 2026
@ti-chi-bot
Copy link
Copy Markdown
Contributor

ti-chi-bot Bot commented May 12, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign disksing for approval. For more information see the Code Review Process.
Please ensure that each of them provides their approval before proceeding.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@ti-chi-bot ti-chi-bot Bot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label May 12, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 12, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 81a70e93-2e91-4753-81ed-542f72b47fd1

📥 Commits

Reviewing files that changed from the base of the PR and between ba4ddf3 and 0ffb59b.

📒 Files selected for processing (2)
  • client/clients/gc/client.go
  • server/apiv2/handlers/safe_point.go

📝 Walkthrough

Walkthrough

Adds option-driven GC-barrier exclusion: new GCStatesAPIOptions, guarded GCState/ClusterGCStates accessors and constructors, client/server wiring for exclusion flags, state-manager reads that optionally omit barriers (and separate singleflight paths), endpoint updates, and comprehensive test changes.

Changes

GC Barrier Exclusion API

Layer / File(s) Summary
GC State models, accessors, and API options
client/clients/gc/client.go, client/clients/gc/client_test.go
GCState and ClusterGCStates now store barrier data internally with presence flags and provide constructors plus Has*/Get* accessors that error when barriers were excluded. GCStatesAPIOptions and helpers (ExcludeGCBarriers, ExcludeGlobalGCBarriers) added. Unit tests validate accessor behavior.
Client API implementation with options
client/gc_client.go
GetGCState and GetAllKeyspacesGCStates accept variadic GCStatesAPIOption; options set protobuf exclusion flags and pbToGCState constructs states with or without barriers using the new constructors.
Server state manager barrier exclusion
pkg/gc/gc_state_manager.go
GetGCState and GetAllKeyspacesGCStates accept excludeGCBarriers and thread it into getGCStateInTransaction; barriers are loaded only when requested and the legacy gc_worker barrier is filtered. Separate singleflight is used per exclusion mode.
Server API endpoint integration
server/gc_service.go, server/api/service_gc_safepoint.go, server/apiv2/handlers/safe_point.go
Handlers pass request flags to the state manager. GetAllGCSafePointV2 defaults to exclusion; GetGCState/GetAllKeyspacesGCStates respect request exclusion flags and conditionally populate global barriers.
Test coverage and accessor validation
pkg/gc/gc_state_manager_test.go, tests/integrations/client/client_test.go, tests/server/gc/gc_test.go, tests/server/api/service_gc_safepoint_test.go, client/clients/gc/client_test.go
Tests updated to call new boolean/option APIs. New tests verify accessor errors and that different exclude parameters do not share singleflight results. Integration tests assert exclusion-by-default and explicit inclusion via accessors.
Go module dependency updates
client/go.mod, go.mod, tests/integrations/go.mod, tools/go.mod
Bumped github.com/pingcap/kvproto pseudo-version/commit in several go.mod files; no new replace directives were added.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant PDServer
  participant GCStateManager
  Client->>PDServer: GetAllKeyspacesGCStates(opts: ExcludeGcBarriers/ExcludeGlobalGcBarriers)
  PDServer->>GCStateManager: GetAllKeyspacesGCStates(ctx, excludeGCBarriers)
  GCStateManager-->>PDServer: ClusterGCStates (with or without global barriers)
  PDServer-->>Client: ClusterGCStates response
Loading

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested labels

lgtm, ok-to-test

Suggested reviewers

  • okJiang
  • bufferflies
  • rleungx

"I'm a rabbit in the code's green glades,
Options sprout where barriers once stayed,
Flags whisper 'exclude' or 'show' on cue,
Accessors guard what callers can view,
Hop, test, and merge — the GC spring renews!"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 52.94% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding support for excluding GC barriers and global GC barriers when retrieving GC states.
Description check ✅ Passed The description provides issue reference, detailed commit message explaining the rationale and implementation approach, acknowledges increased code complexity, includes unit and integration tests, and lists the kvproto dependency requirement.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@MyonKeminta MyonKeminta marked this pull request as draft May 12, 2026 11:09
@ti-chi-bot ti-chi-bot Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label May 12, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@client/clients/gc/client.go`:
- Around line 314-362: Add GoDoc comments for the exported accessors: place a
comment starting with the exact function name above HasGCBarriers and
GetGCBarriers on type GCState and above HasGlobalGCBarriers and
GetGlobalGCBarriers on type ClusterGCStates; each comment should begin with the
function name, briefly describe what it returns (e.g., whether GC
barriers/global GC barriers are available) and for Get* methods document the
returned value and the error condition when the corresponding Has* is false.
Ensure the comments follow GoDoc style (start with the identifier) and mention
the types GCState and ClusterGCStates where appropriate.

In `@pkg/gc/gc_state_manager.go`:
- Around line 703-709: GetAllKeyspacesGCStates currently uses
m.allKeyspacesGCStatesSingleFlight.Do without incorporating the
excludeGCBarriers flag into the singleflight key, so concurrent calls with
different excludeGCBarriers values can return the wrong shape; fix by including
excludeGCBarriers in the singleflight key used when calling Do (e.g. append a
":barriers=true/false" suffix or otherwise derive a unique key per
excludeGCBarriers) and keep calling getAllKeyspacesGCStatesImpl(execCtx,
excludeGCBarriers) inside the lambda so each distinct key has its own
in-flight/result.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 04a38f0a-4825-48c2-85b0-de1330aed450

📥 Commits

Reviewing files that changed from the base of the PR and between f6653ed and c5e24d8.

⛔ Files ignored due to path filters (4)
  • client/go.sum is excluded by !**/*.sum
  • go.sum is excluded by !**/*.sum
  • tests/integrations/go.sum is excluded by !**/*.sum
  • tools/go.sum is excluded by !**/*.sum
📒 Files selected for processing (14)
  • client/clients/gc/client.go
  • client/clients/gc/client_test.go
  • client/gc_client.go
  • client/go.mod
  • go.mod
  • pkg/gc/gc_state_manager.go
  • pkg/gc/gc_state_manager_test.go
  • server/api/service_gc_safepoint.go
  • server/gc_service.go
  • tests/integrations/client/client_test.go
  • tests/integrations/go.mod
  • tests/server/api/service_gc_safepoint_test.go
  • tests/server/gc/gc_test.go
  • tools/go.mod

Comment thread client/clients/gc/client.go
Comment thread pkg/gc/gc_state_manager.go
func (m *GCStateManager) GetAllKeyspacesGCStates(ctx context.Context, excludeGCBarriers bool) (map[uint32]GCState, error) {
return m.allKeyspacesGCStatesSingleFlight.Do(ctx, func(execCtx context.Context) (map[uint32]GCState, error) {
result, err := m.getAllKeyspacesGCStatesImpl(execCtx)
result, err := m.getAllKeyspacesGCStatesImpl(execCtx, excludeGCBarriers)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

singleflight.Do uses ctx as the dedup key, but excludeGCBarriers is not included in the key. When two concurrent calls pass different excludeGCBarriers values, only one lambda will execute, and the other caller will get a result of the wrong shape (for example, caller A passes excludeGCBarriers=false expecting to get GC barriers, but after dedup, it gets the result from caller B who passed excludeGCBarriers=true — no barriers).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not the builtin singleflight but the hand-written linearizable version OrderedSingleFlight, and it doesn't support key yet.
I added a separated singleflight fir it.

Signed-off-by: MyonKeminta <MyonKeminta@users.noreply.github.com>
@MyonKeminta MyonKeminta marked this pull request as ready for review May 14, 2026 11:11
@ti-chi-bot ti-chi-bot Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label May 14, 2026
Signed-off-by: MyonKeminta <MyonKeminta@users.noreply.github.com>
Signed-off-by: MyonKeminta <MyonKeminta@users.noreply.github.com>
Signed-off-by: MyonKeminta <MyonKeminta@users.noreply.github.com>
}

// DefaultGCStatesAPIOptions returns the default options for GC states API.
func DefaultGCStatesAPIOptions() GCStatesAPIOptions {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes the Go client default behavior: existing callers of GetGCState/GetAllKeyspacesGCStates will silently stop receiving barriers. Can we keep the old default and make exclusion opt-in, or call this out as a breaking change?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As it's hard to push all callers to update their usage, I suggest let this be a breaking change. Callers that really needs the GC barriers will receive compile error, and is forced to switch to the safe retriver function; then if they missed the new options, they will get an error.
Actually, I expect that there's no such usage for now. If so, nothing will happen after upgrading the PD client.

KeyspaceID uint32
TxnSafePoint uint64
GCSafePoint uint64
hasGCBarriers bool
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing the exported barrier fields breaks source compatibility for existing users. Could we keep exported fields for compatibility and add Has/Get helpers to distinguish not-fetched from an empty result?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto. And this prevents misuse.

Comment thread client/gc_client.go
TxnSafePoint: pb.GetTxnSafePoint(),
GCSafePoint: pb.GetGcSafePoint(),
GCBarriers: gcBarriers,
if !excludeGCBarriers {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before this branch, we already allocate and convert all returned barriers. During rolling upgrades, an old PD may still return barriers even when the new client requested exclusion, so we can return early before the conversion.

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

Labels

dco-signoff: yes Indicates the PR's author has signed the dco. release-note-none Denotes a PR that doesn't merit a release note. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants