Skip to content

br: add keyspace-aware GC safepoint support for backup and restore (#65483) - #68863

Closed
ti-chi-bot wants to merge 4 commits into
pingcap:release-8.5from
ti-chi-bot:cherry-pick-65483-to-release-8.5
Closed

ti-chi-bot wants to merge 4 commits into
pingcap:release-8.5from
ti-chi-bot:cherry-pick-65483-to-release-8.5

Conversation

@ti-chi-bot

@ti-chi-bot ti-chi-bot commented Jun 2, 2026 •

Copy link
Copy Markdown
Member

This is an automated cherry-pick of #65483

What problem does this PR solve?

Issue Number: close #65482

Problem Summary:

BR currently uses the deprecated global GC safepoint API (pd.Client.UpdateServiceGCSafePoint) which doesn't support keyspace isolation. When users specify --keyspace-name parameter, BR should use the new per-keyspace GC barrier API (GCStatesClient.SetGCBarrier / DeleteGCBarrier) instead.

What changed and how does it work?

This PR introduces a GC manager abstraction layer that automatically selects the appropriate GC implementation based on user's --keyspace-name parameter:

New files:

  • gc_manager.go: Factory function and wrapper functions
  • gc_manager_unified.go: Non-keyspace implementation using deprecated global API (backward compatible)
  • gc_manager_keyspace.go: Keyspace implementation using new GC barrier API

Design:

GCSafePointManager (interface)
├── UnifiedGCManager    (--keyspace-name NOT provided)
│   └── Uses pd.Client.UpdateServiceGCSafePoint (deprecated, global)
└── KeyspaceGCManager   (--keyspace-name IS provided)
    └── Uses GCStatesClient.SetGCBarrier/DeleteGCBarrier (per-keyspace)

Updated callers:

  • backup.go: Use StartServiceSafePointKeeperWithStorage
  • restore.go: Use UpdateServiceSafePointWithStorage
  • stream.go: Use StartServiceSafePointKeeperWithStorage
  • backup_ebs.go, restore_data.go, log_client/client.go: Updated accordingly

Check List

Tests

  • Unit test
  • Integration test
  • Manual test (add detailed scripts or steps below)
  • No need to test

Side effects

  • Performance regression: Consumes more CPU
  • Performance regression: Consumes more Memory
  • Breaking backward compatibility

Documentation

  • Affects user behaviors
  • Contains syntax changes
  • Contains variable changes
  • Contains experimental features
  • Changes MySQL compatibility

Release note

None

Summary by CodeRabbit

Release Notes

  • New Features

    • Added support for keyspace-specific garbage collection barriers during backup and restore operations.
    • Added unified handling for global and keyspace-scoped GC safe points.
  • Improvements

    • Improved safe-point management across backup, restore, log backup, streaming, and snapshot workflows.
    • Added automatic barrier validation, renewal, and cleanup to help protect data.
    • Expanded test coverage for global and keyspace GC behavior.

Signed-off-by: ti-chi-bot <ti-community-prow-bot@tidb.io>
@ti-chi-bot ti-chi-bot added do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. ok-to-test Indicates a PR is ready to be tested. 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. type/cherry-pick-for-release-8.5 This PR is cherry-picked to release-8.5 from a source PR. labels Jun 2, 2026
@ti-chi-bot

Copy link
Copy Markdown
Member Author

@RidRisR This PR has conflicts, I have hold it.
Please resolve them or ask others to resolve them, then comment /unhold to remove the hold label.

@ti-chi-bot

ti-chi-bot Bot commented Jun 2, 2026

Copy link
Copy Markdown

@ti-chi-bot: ## If you want to know how to resolve it, please read the guide in TiDB Dev Guide.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the ti-community-infra/tichi repository.

@coderabbitai

coderabbitai Bot commented Jun 2, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3118f818-e22b-4bfc-80d1-ebb1d7aef4ed

📥 Commits

Reviewing files that changed from the base of the PR and between 6836955 and ac9448d.

📒 Files selected for processing (3)
  • br/pkg/gc/manager_keyspace.go
  • br/pkg/gc/manager_test.go
  • br/pkg/gc/mock_test.go

📝 Walkthrough

Walkthrough

This PR moves BR GC safe-point handling from br/pkg/utils into br/pkg/gc. It adds global and keyspace-scoped managers, updates backup, restore, stream, operator, and log restore workflows, and adds unit and integration coverage.

Changes

GC Manager Abstraction and Keyspace Support

Layer / File(s) Summary
GC manager contract and implementations
br/pkg/gc/BUILD.bazel, br/pkg/gc/manager.go, br/pkg/gc/manager_global.go, br/pkg/gc/manager_keyspace.go
Defines the Manager interface and selects global or keyspace implementations. Global mode uses PD safe-point APIs. Keyspace mode uses PD V2 GC barrier APIs.
Manager-based safe-point keeper
br/pkg/gc/safepoint.go
Updates safe-point validation and keeper refreshes to use gc.Manager.
GC manager and keeper tests
br/pkg/gc/mock_test.go, br/pkg/gc/manager_test.go, br/pkg/gc/safepoint_test.go
Adds mocks and tests for both scopes, safe-point lifecycle, validation, refresh, cancellation, and errors.
Connection and backup client integration
br/pkg/conn/*, br/pkg/backup/*
Initializes managers from storage keyspace IDs. Updates backup timestamp checks, IDs, TTL defaults, and test setup.
Backup task migration
br/pkg/task/backup.go, br/pkg/task/backup_ebs.go, br/pkg/task/common_test.go
Uses GC package types and constants. Starts keepers and deletes service safe points through the manager.
Restore and stream migration
br/pkg/task/restore.go, br/pkg/task/restore_data.go, br/pkg/task/stream.go
Migrates safe-point creation, validation, refresh, cleanup, and TTL handling to gc.Manager.
Operator and log client migration
br/pkg/task/operator/prepare_snap.go, br/pkg/restore/log_client/client.go
Uses global or keyspace-derived managers for snapshot pause and log restore flows.
Utils cleanup
br/pkg/utils/BUILD.bazel
Removes the old safe-point sources and related dependencies from utils.
Integration coverage
br/tests/br_gc_keyspace_full_backup/run.sh, tests/realtikvtest/brietest/*, br/tests/run_group_br_tests.sh
Adds global and keyspace GC integration tests and registers the shell test. The Bazel file contains merge-conflict markers around shard_count.

Estimated code review effort: 4 (Complex) | ~60 minutes

Suggested reviewers: ridrisr, yujuncen

Poem

A rabbit checks barriers in global and keyspace lanes,
Safe points refresh through manager chains.
Backup and restore now share the way,
Stream tasks keep old GC drift at bay.
Tests mark each scope with files bright—
Hop, hop, GC is wired right!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The implementation addresses keyspace-aware GC management, caller updates, backward compatibility, and tests, but the Bazel summary reports unresolved conflict markers. Remove all unresolved merge-conflict markers from tests/realtikvtest/brietest/BUILD.bazel and verify the target builds successfully.
Docstring Coverage ⚠️ Warning Docstring coverage is 58.54% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: adding keyspace-aware GC safepoint support for BR.
Description check ✅ Passed The description includes the required issue, problem, implementation, testing, side-effect, documentation, and release-note sections.
Out of Scope Changes check ✅ Passed The changes remain focused on keyspace-aware GC safepoint handling, related caller updates, build dependencies, and corresponding unit and integration tests.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

Error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions
The command is terminated due to an error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions


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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 10

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
br/pkg/gc/safepoint.go (1)

78-93: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Reject or clamp TTLs below 3 seconds before creating the ticker.

updateGapTime is computed with integer division, so sp.TTL == 1 or 2 makes Line 91 evaluate to 0, and time.NewTicker(0) panics. Since GC TTL is user-configurable, this is a reachable crash path.

Proposed fix
 	if sp.ID == "" || sp.TTL <= 0 {
 		return errors.Annotatef(berrors.ErrInvalidArgument, "invalid service safe point %v", sp)
 	}
+	if sp.TTL < preUpdateServiceSafePointFactor {
+		return errors.Annotatef(
+			berrors.ErrInvalidArgument,
+			"service safe point TTL %d is too small; must be at least %d seconds",
+			sp.TTL,
+			preUpdateServiceSafePointFactor,
+		)
+	}
 	if err := CheckGCSafePoint(ctx, mgr, sp.BackupTS); err != nil {
 		return errors.Trace(err)
 	}
@@
-	updateGapTime := time.Duration(sp.TTL) * time.Second / preUpdateServiceSafePointFactor
+	updateGapTime := time.Duration(sp.TTL) * time.Second / preUpdateServiceSafePointFactor
 	updateTick := time.NewTicker(updateGapTime)
🤖 Prompt for 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.

In `@br/pkg/gc/safepoint.go` around lines 78 - 93, The code can panic when sp.TTL
is 1 or 2 because updateGapTime becomes zero and time.NewTicker(0) panics;
before creating the ticker (and before calling mgr.SetServiceSafePoint),
validate or clamp sp.TTL to a safe minimum (e.g., reject TTLs < 3 seconds with
an error from the same validation block that checks sp.ID/TTL, or set sp.TTL = 3
when computing updateGapTime), then compute updateGapTime =
time.Duration(sp.TTL) * time.Second / preUpdateServiceSafePointFactor and create
updateTick and checkTick; reference sp.TTL, updateGapTime,
preUpdateServiceSafePointFactor, updateTick and the earlier validation that
returns ErrInvalidArgument so the fix is applied in the same
validation/initialization area.
🧹 Nitpick comments (3)
br/pkg/conn/conn.go (1)

279-285: ⚡ Quick win

Add a doc comment for GetGCManager.

SetGcManager is documented, but the new exported getter is not. Please add a short doc comment so the exported pair stays consistent and godoc-clean.

As per coding guidelines, "Keep exported-symbol doc comments, and prefer semantic constraints over name restatement."

🤖 Prompt for 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.

In `@br/pkg/conn/conn.go` around lines 279 - 285, Add a godoc comment for the
exported GetGCManager method on type Mgr to match the existing SetGcManager
documentation and keep exported-symbol docs consistent; write a concise,
semantic comment above func (mgr *Mgr) GetGCManager() gc.Manager that explains
what GC manager is returned or under what conditions (e.g., "GetGCManager
returns the current garbage-collection manager used by the Mgr." or similar)
without restating the method name.
br/tests/br_gc_keyspace_full_backup/run.sh (1)

74-81: ⚡ Quick win

Also assert the keyspace delete marker stays absent in global mode.

This script only proves SIG_KS_SET was not written. A regression that routes cleanup through DeleteGCBarrier would still pass, because SIG_KS_DEL is never checked even though br/pkg/gc/manager_keyspace.go writes that marker on delete.

Suggested patch
 wait "$global_pid" || { echo "Global backup failed"; exit 1; }
 wait_file_exists "$SIG_GLOBAL_DEL" "(waiting global delete)"
+test ! -f "$SIG_KS_DEL"
 
 safe_point=$(run_pd_ctl -u https://$PD_ADDR service-gc-safepoint)
 if echo "$safe_point" | grep -q "\"service_id\": \"$global_sp_id\""; then
🤖 Prompt for 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.

In `@br/tests/br_gc_keyspace_full_backup/run.sh` around lines 74 - 81, Add an
assertion that the keyspace delete marker (SIG_KS_DEL) is absent in global mode:
after verifying the global safepoint was removed, check that the SIG_KS_DEL
marker file does not exist (similar to how SIG_KS_SET is checked) and fail the
script if it is present; reference the existing variables SIG_KS_DEL and
SIG_KS_SET and the helper wait_file_exists/run_pd_ctl pattern so the new check
mirrors the other marker checks (use wait_file_not_exists or a direct test and
exit 1 if SIG_KS_DEL is found).
br/pkg/gc/mock_test.go (1)

87-99: ⚡ Quick win

Surface fixture teardown failures instead of discarding them.

The shared cleanup helper currently ignores rm.Close, db.Close, and os.RemoveAll errors. If fixture shutdown starts failing, these tests will hide the root cause and become much harder to debug.

As per coding guidelines, "Go code: Keep error handling actionable and contextual; avoid silently swallowing errors"

🤖 Prompt for 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.

In `@br/pkg/gc/mock_test.go` around lines 87 - 99, The cleanup helper in t.Cleanup
currently swallows errors from rm.Close, db.Close, and os.RemoveAll; change it
to check each call's returned error and fail the test with context when non-nil
(e.g. if err := rm.Close(); err != nil { t.Fatalf("rm.Close failed: %v", err)
}), do the same for db.Close and os.RemoveAll including the dbPath/logPath in
the message so teardown failures surface (refer to the t.Cleanup block and
variables rm, db, dbPath, logPath).
🤖 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 `@br/pkg/gc/manager_keyspace.go`:
- Around line 14-17: The build fails because github.com/tikv/client-go/v2 pulls
in github.com/tikv/pd/client/circuitbreaker which is missing from the pinned PD
client; to fix, update the module/dependency pinning so the PD client package
version that includes circuitbreaker is used (or backport that package) and
update go.mod and Bazel/go dependency files accordingly; ensure the PD client
you pin still provides GetGCStatesClient, SetGCBarrier, and DeleteGCBarrier
(used by manager_keyspace.go via clients/gc) and re-run go test ./br/pkg/gc to
verify the import resolution.

In `@br/pkg/gc/mock_test.go`:
- Line 1: Replace the one-line header in br/pkg/gc/mock_test.go with the
standard TiDB Go license boilerplate (full copyright + Apache-2.0 block) used
across the repo; apply the same replacement to other new *.go test files so that
files like mock_test.go contain the required multi-line TiDB license header at
the top before the package declaration.

In `@br/pkg/gc/safepoint_test.go`:
- Around line 44-61: The test Concurrent_Uniqueness in TestMakeSafePointID calls
require.False(t, ...) from worker goroutines which is unsafe; change it so
workers only send their generated IDs back (e.g., via a channel or append to a
protected slice/map) and do uniqueness checks and the require.False/assertions
on the main test goroutine after wg.Wait(); update references to
gc.MakeSafePointID (worker) and remove require.False from the anonymous
goroutine so the main goroutine reads all IDs, detects duplicates, and calls
require on the results.

In `@br/pkg/gc/safepoint.go`:
- Around line 58-60: The helpers (e.g., CheckGCSafePoint) currently call
mgr.GetGCSafePoint without validating mgr, causing a panic when mgr is nil;
update CheckGCSafePoint and the other helper(s) in the same file (lines ~73-86)
to check if mgr == nil at the top and immediately return ErrInvalidArgument if
so, avoiding panics and making failures predictable for miswired tests and
callers. Ensure the nil-check precedes any use of mgr (including
mgr.GetGCSafePoint) and return the existing ErrInvalidArgument sentinel value.

In `@br/pkg/restore/log_client/client.go`:
- Around line 1993-2003: The defer uses the original request context (ctx) when
calling gcMgr.DeleteServiceSafePoint, which can be canceled/expired and prevent
safepoint removal; change the teardown to create a fresh bounded background
context (e.g., ctx2 := context.WithTimeout(context.Background(),
<reasonable-duration>) with cancel) and call gcMgr.DeleteServiceSafePoint(ctx2,
sp) inside the defer, then cancel ctx2 after the delete; ensure this new context
and its cancel are used instead of ctx while keeping the existing
gcSafePointKeeperCancel call and referencing cctx, gcSafePointKeeperCancel,
gcMgr.DeleteServiceSafePoint, and sp.

In `@br/pkg/task/common_test.go`:
- Around line 13-18: Resolve the merge conflict markers in the import block by
removing the `<<<<<<<`, `=======`, and `>>>>>>>` lines and restoring a single
import list that includes both the required packages
`github.com/pingcap/tidb/br/pkg/storage` (needed for storage.BackendOptions) and
`github.com/pingcap/tidb/br/pkg/gc` (needed for gc.DefaultBRGCSafePointTTL`),
and remove `github.com/pingcap/tidb/br/pkg/utils` if it remains and is unused in
the file.

In `@br/pkg/task/stream.go`:
- Around line 437-445: streamMgr.setGCSafePoint currently always calls
GetGCManager().SetServiceSafePoint which fails to remove a safepoint when TTL==0
in keyspace mode; update setGCSafePoint to detect sp.TTL == 0 (or the equivalent
sentinel used by RunStreamStop) and call
GetGCManager().DeleteServiceSafePoint(ctx, sp) instead of SetServiceSafePoint
for removals, otherwise keep calling SetServiceSafePoint(ctx, sp); reference the
streamMgr.setGCSafePoint function and GetGCManager().DeleteServiceSafePoint /
SetServiceSafePoint methods when making the change.

In `@br/pkg/utils/BUILD.bazel`:
- Around line 61-65: Remove the unresolved git merge markers and decide which
dependency(s) should remain: either keep
"`@com_github_tikv_client_go_v2//oracle`", keep
"`@com_github_prometheus_client_golang//prometheus/promhttp`", or include both if
required by the package; specifically delete the lines starting with "<<<<<<<",
"=======", and ">>>>>>>" and update the dependency list to contain only the
correct Bazel labels so the BUILD rule is syntactically valid.

In `@tests/realtikvtest/brietest/BUILD.bazel`:
- Around line 19-22: Remove the leftover merge-conflict markers (<<<<<<<,
=======, >>>>>>>) from the BUILD.bazel fragment and ensure the brietest_test
target has the intended attribute shard_count = 27 present; specifically, delete
the conflict markers and keep the line "shard_count = 27," inside the
brietest_test target so Bazel can parse the file cleanly.

In `@tests/realtikvtest/brietest/gc_keyspace_test.go`:
- Around line 45-48: Save the original global config before mutating it (call
config.GetGlobalConfig() into a variable like prevCfg), then after setting
cfg.Store and cfg.Path and calling config.StoreGlobalConfig(cfg) register a
t.Cleanup that restores the original via config.StoreGlobalConfig(prevCfg); use
the same variable names (cfg, prevCfg) and t.Cleanup so the process-wide state
is reverted when the test finishes.

---

Outside diff comments:
In `@br/pkg/gc/safepoint.go`:
- Around line 78-93: The code can panic when sp.TTL is 1 or 2 because
updateGapTime becomes zero and time.NewTicker(0) panics; before creating the
ticker (and before calling mgr.SetServiceSafePoint), validate or clamp sp.TTL to
a safe minimum (e.g., reject TTLs < 3 seconds with an error from the same
validation block that checks sp.ID/TTL, or set sp.TTL = 3 when computing
updateGapTime), then compute updateGapTime = time.Duration(sp.TTL) * time.Second
/ preUpdateServiceSafePointFactor and create updateTick and checkTick; reference
sp.TTL, updateGapTime, preUpdateServiceSafePointFactor, updateTick and the
earlier validation that returns ErrInvalidArgument so the fix is applied in the
same validation/initialization area.

---

Nitpick comments:
In `@br/pkg/conn/conn.go`:
- Around line 279-285: Add a godoc comment for the exported GetGCManager method
on type Mgr to match the existing SetGcManager documentation and keep
exported-symbol docs consistent; write a concise, semantic comment above func
(mgr *Mgr) GetGCManager() gc.Manager that explains what GC manager is returned
or under what conditions (e.g., "GetGCManager returns the current
garbage-collection manager used by the Mgr." or similar) without restating the
method name.

In `@br/pkg/gc/mock_test.go`:
- Around line 87-99: The cleanup helper in t.Cleanup currently swallows errors
from rm.Close, db.Close, and os.RemoveAll; change it to check each call's
returned error and fail the test with context when non-nil (e.g. if err :=
rm.Close(); err != nil { t.Fatalf("rm.Close failed: %v", err) }), do the same
for db.Close and os.RemoveAll including the dbPath/logPath in the message so
teardown failures surface (refer to the t.Cleanup block and variables rm, db,
dbPath, logPath).

In `@br/tests/br_gc_keyspace_full_backup/run.sh`:
- Around line 74-81: Add an assertion that the keyspace delete marker
(SIG_KS_DEL) is absent in global mode: after verifying the global safepoint was
removed, check that the SIG_KS_DEL marker file does not exist (similar to how
SIG_KS_SET is checked) and fail the script if it is present; reference the
existing variables SIG_KS_DEL and SIG_KS_SET and the helper
wait_file_exists/run_pd_ctl pattern so the new check mirrors the other marker
checks (use wait_file_not_exists or a direct test and exit 1 if SIG_KS_DEL is
found).
🪄 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: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 57a0aa7c-0068-4df4-acec-4032a83a2fd1

📥 Commits

Reviewing files that changed from the base of the PR and between e198e2d and 0cd2a74.

📒 Files selected for processing (31)
  • br/pkg/backup/BUILD.bazel
  • br/pkg/backup/client.go
  • br/pkg/backup/client_test.go
  • br/pkg/conn/BUILD.bazel
  • br/pkg/conn/conn.go
  • br/pkg/gc/BUILD.bazel
  • br/pkg/gc/manager.go
  • br/pkg/gc/manager_global.go
  • br/pkg/gc/manager_keyspace.go
  • br/pkg/gc/manager_test.go
  • br/pkg/gc/mock_test.go
  • br/pkg/gc/safepoint.go
  • br/pkg/gc/safepoint_test.go
  • br/pkg/restore/log_client/BUILD.bazel
  • br/pkg/restore/log_client/client.go
  • br/pkg/task/BUILD.bazel
  • br/pkg/task/backup.go
  • br/pkg/task/backup_ebs.go
  • br/pkg/task/common_test.go
  • br/pkg/task/operator/BUILD.bazel
  • br/pkg/task/operator/prepare_snap.go
  • br/pkg/task/restore.go
  • br/pkg/task/restore_data.go
  • br/pkg/task/stream.go
  • br/pkg/utils/BUILD.bazel
  • br/pkg/utils/safe_point_test.go
  • br/tests/br_gc_keyspace_full_backup/run.sh
  • br/tests/run_group_br_tests.sh
  • tests/realtikvtest/brietest/BUILD.bazel
  • tests/realtikvtest/brietest/gc_keyspace_test.go
  • tests/realtikvtest/brietest/operator_test.go
💤 Files with no reviewable changes (1)
  • br/pkg/utils/safe_point_test.go

Comment thread br/pkg/gc/manager_keyspace.go
Comment thread br/pkg/gc/mock_test.go
@@ -0,0 +1,214 @@
// Copyright 2025 PingCAP, Inc. Licensed under Apache-2.0.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Use the standard TiDB Go license header.

This abbreviated one-line header doesn't match the required TiDB boilerplate for new *.go files. Please replace it here and in the other new Go test files with the standard copyright + Apache 2.0 block.

As per coding guidelines, "**/*.go: For new source files (*.go): include the standard TiDB license header (copyright + Apache 2.0)`"

🤖 Prompt for 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.

In `@br/pkg/gc/mock_test.go` at line 1, Replace the one-line header in
br/pkg/gc/mock_test.go with the standard TiDB Go license boilerplate (full
copyright + Apache-2.0 block) used across the repo; apply the same replacement
to other new *.go test files so that files like mock_test.go contain the
required multi-line TiDB license header at the top before the package
declaration.

Comment on lines +44 to +61
t.Run("Concurrent_Uniqueness", func(t *testing.T) {
var mu sync.Mutex
ids := make(map[string]bool)
count := 100

var wg sync.WaitGroup
for i := 0; i < count; i++ {
wg.Add(1)
go func() {
defer wg.Done()
id := gc.MakeSafePointID()
mu.Lock()
defer mu.Unlock()
require.False(t, ids[id], "duplicate ID generated: %s", id)
ids[id] = true
}()
}
wg.Wait()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Does github.com/stretchr/testify allow calling require/assert helpers from goroutines created inside a test?

💡 Result:

No, you should not call testify's require or assert helpers from goroutines created inside a test [1][2][3]. According to the official documentation for github.com/stretchr/testify, these functions must be called from the goroutine running the test or benchmark function itself [1][2][3]. Calling them from other goroutines can result in race conditions [1][2][3]. This restriction exists primarily because testify helpers interact with the standard library's testing.T object [4][5]. Specifically, the require package uses t.FailNow, and the assert package uses t.Errorf [6][4]. The Go testing package documentation mandates that t.FailNow must be called from the goroutine running the test, as it uses runtime.Goexit to terminate that specific goroutine [4][5]. While t.Errorf does not have the same immediate termination behavior, using either from concurrent goroutines is generally discouraged to avoid data races and ensure test results are correctly associated with the main test execution flow [1][2][6][5]. If you need to perform assertions within a goroutine, it is standard practice to use channels or other synchronization mechanisms to collect the results and perform the assertions on the main test goroutine [6].

Citations:


Move require assertions out of the worker goroutines in TestMakeSafePointID/Concurrent_Uniqueness.

In br/pkg/gc/safepoint_test.go (lines 44-61), the goroutines call require.False(t, ...). testify/require uses testing.T (via FailNow) and should only be called from the test/benchmark goroutine; doing it from spawned goroutines can make the test flaky/racy. Collect duplicate IDs from workers (e.g., channel/atomic), then perform the require once after wg.Wait() on the main test goroutine.

🤖 Prompt for 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.

In `@br/pkg/gc/safepoint_test.go` around lines 44 - 61, The test
Concurrent_Uniqueness in TestMakeSafePointID calls require.False(t, ...) from
worker goroutines which is unsafe; change it so workers only send their
generated IDs back (e.g., via a channel or append to a protected slice/map) and
do uniqueness checks and the require.False/assertions on the main test goroutine
after wg.Wait(); update references to gc.MakeSafePointID (worker) and remove
require.False from the anonymous goroutine so the main goroutine reads all IDs,
detects duplicates, and calls require on the results.

Comment thread br/pkg/gc/safepoint.go
Comment on lines +58 to 60
func CheckGCSafePoint(ctx context.Context, mgr Manager, ts uint64) error {
safePoint, err := mgr.GetGCSafePoint(ctx)
if err != nil {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fail fast when the GC manager is missing.

These new helpers call through mgr immediately. A nil gc.Manager now panics, and the new test wiring in br/pkg/backup/client_test.go already shows zero-value conn.Mgr instances need manual GC-manager initialization. Returning ErrInvalidArgument here would make miswired tests and alternate callers fail predictably.

Proposed fix
 func CheckGCSafePoint(ctx context.Context, mgr Manager, ts uint64) error {
+	if mgr == nil {
+		return errors.Annotate(berrors.ErrInvalidArgument, "gc manager is required")
+	}
 	safePoint, err := mgr.GetGCSafePoint(ctx)
 	if err != nil {
 		log.Warn("fail to get GC safe point", zap.Error(err))
@@
 func StartServiceSafePointKeeper(
 	ctx context.Context,
 	sp BRServiceSafePoint,
 	mgr Manager,
 ) error {
+	if mgr == nil {
+		return errors.Annotate(berrors.ErrInvalidArgument, "gc manager is required")
+	}
 	if sp.ID == "" || sp.TTL <= 0 {
 		return errors.Annotatef(berrors.ErrInvalidArgument, "invalid service safe point %v", sp)
 	}

Also applies to: 73-86

🤖 Prompt for 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.

In `@br/pkg/gc/safepoint.go` around lines 58 - 60, The helpers (e.g.,
CheckGCSafePoint) currently call mgr.GetGCSafePoint without validating mgr,
causing a panic when mgr is nil; update CheckGCSafePoint and the other helper(s)
in the same file (lines ~73-86) to check if mgr == nil at the top and
immediately return ErrInvalidArgument if so, avoiding panics and making failures
predictable for miswired tests and callers. Ensure the nil-check precedes any
use of mgr (including mgr.GetGCSafePoint) and return the existing
ErrInvalidArgument sentinel value.

Comment on lines 1993 to 2003
cctx, gcSafePointKeeperCancel := context.WithCancel(ctx)
defer func() {
log.Info("start to remove gc-safepoint keeper")
// close the gc safe point keeper at first
gcSafePointKeeperCancel()
// set the ttl to 0 to remove the gc-safe-point
sp.TTL = 0
if err := utils.UpdateServiceSafePoint(ctx, pdClient, sp); err != nil {
log.Warn("failed to update service safe point, backup may fail if gc triggered",
// remove the gc-safe-point
if err := gcMgr.DeleteServiceSafePoint(ctx, sp); err != nil {
log.Warn("failed to remove service safe point, backup may fail if gc triggered",
zap.Error(err),
)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use a fresh cleanup context for safepoint removal.

If this helper returns because ctx is canceled or its deadline expires, gcMgr.DeleteServiceSafePoint(ctx, sp) will fail immediately and leave the service safepoint / keyspace barrier behind until TTL expiry. The teardown should use its own bounded background context instead of the request context.

Suggested fix
 	defer func() {
 		log.Info("start to remove gc-safepoint keeper")
 		// close the gc safe point keeper at first
 		gcSafePointKeeperCancel()
+		cleanupCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
+		defer cancel()
 		// remove the gc-safe-point
-		if err := gcMgr.DeleteServiceSafePoint(ctx, sp); err != nil {
+		if err := gcMgr.DeleteServiceSafePoint(cleanupCtx, sp); err != nil {
 			log.Warn("failed to remove service safe point, backup may fail if gc triggered",
 				zap.Error(err),
 			)
 		}
 		log.Info("finish removing gc-safepoint keeper")
 	}()
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
cctx, gcSafePointKeeperCancel := context.WithCancel(ctx)
defer func() {
log.Info("start to remove gc-safepoint keeper")
// close the gc safe point keeper at first
gcSafePointKeeperCancel()
// set the ttl to 0 to remove the gc-safe-point
sp.TTL = 0
if err := utils.UpdateServiceSafePoint(ctx, pdClient, sp); err != nil {
log.Warn("failed to update service safe point, backup may fail if gc triggered",
// remove the gc-safe-point
if err := gcMgr.DeleteServiceSafePoint(ctx, sp); err != nil {
log.Warn("failed to remove service safe point, backup may fail if gc triggered",
zap.Error(err),
)
}
defer func() {
log.Info("start to remove gc-safepoint keeper")
// close the gc safe point keeper at first
gcSafePointKeeperCancel()
cleanupCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
// remove the gc-safe-point
if err := gcMgr.DeleteServiceSafePoint(cleanupCtx, sp); err != nil {
log.Warn("failed to remove service safe point, backup may fail if gc triggered",
zap.Error(err),
)
}
log.Info("finish removing gc-safepoint keeper")
}()
🤖 Prompt for 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.

In `@br/pkg/restore/log_client/client.go` around lines 1993 - 2003, The defer uses
the original request context (ctx) when calling gcMgr.DeleteServiceSafePoint,
which can be canceled/expired and prevent safepoint removal; change the teardown
to create a fresh bounded background context (e.g., ctx2 :=
context.WithTimeout(context.Background(), <reasonable-duration>) with cancel)
and call gcMgr.DeleteServiceSafePoint(ctx2, sp) inside the defer, then cancel
ctx2 after the delete; ensure this new context and its cancel are used instead
of ctx while keeping the existing gcSafePointKeeperCancel call and referencing
cctx, gcSafePointKeeperCancel, gcMgr.DeleteServiceSafePoint, and sp.

Comment thread br/pkg/task/common_test.go Outdated
Comment on lines +13 to +18
<<<<<<< HEAD
"github.com/pingcap/tidb/br/pkg/storage"
"github.com/pingcap/tidb/br/pkg/utils"
=======
"github.com/pingcap/tidb/br/pkg/gc"
>>>>>>> cb138ca3deb (br: add keyspace-aware GC safepoint support for backup and restore (#65483))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
sed -n '1,30p' br/pkg/task/common_test.go
rg -n '^(<<<<<<<|=======|>>>>>>>)' br/pkg/task/common_test.go

Repository: pingcap/tidb

Length of output: 949


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file="br/pkg/task/common_test.go"

rg -n "storage\.BackendOptions|gc\.DefaultBRGCSafePointTTL" "$file" || true
rg -n "expectedDefaultConfig|expectedDefaultBackupConfig" "$file" || true
sed -n '1,120p' "$file"

Repository: pingcap/tidb

Length of output: 4130


🏁 Script executed:

#!/bin/bash
set -euo pipefail
file="br/pkg/task/common_test.go"
rg -n "utils\." "$file" || true

Repository: pingcap/tidb

Length of output: 38


🏁 Script executed:

#!/bin/bash
set -euo pipefail
file="br/pkg/task/common_test.go"

rg -n "br/pkg/utils|\"github.com/pingcap/tidb/br/pkg/utils\"|utils\." "$file" || true
rg -n "br/pkg/gc|\"github.com/pingcap/tidb/br/pkg/gc\"|gc\." "$file" || true

Repository: pingcap/tidb

Length of output: 181


🏁 Script executed:

#!/bin/bash
set -euo pipefail
file="br/pkg/task/common_test.go"
rg -n "\butils\b" "$file" || true

Repository: pingcap/tidb

Length of output: 99


🏁 Script executed:

#!/bin/bash
set -euo pipefail
file="br/pkg/task/common_test.go"

echo "---- conflict markers ----"
rg -n '^(<<<<<<<|=======|>>>>>>>)' "$file" || true

echo "---- utils usage ----"
rg -n '\butils\.' "$file" || true

echo "---- storage usage ----"
rg -n '\bstorage\.' "$file" || true

echo "---- gc usage ----"
rg -n '\bgc\.' "$file" || true

echo "---- import block (around lines 1-60) ----"
sed -n '1,70p' "$file"

Repository: pingcap/tidb

Length of output: 2211


Resolve merge-conflict markers in br/pkg/task/common_test.go import block — the unresolved <<<<<<</=======/>>>>>>> markers keep this test file from compiling. After resolving, keep both br/pkg/storage (used via storage.BackendOptions) and br/pkg/gc (used via gc.DefaultBRGCSafePointTTL); br/pkg/utils is not referenced in this file and should be removed if it remains unused.

Suggested fix
-<<<<<<< HEAD
-	"github.com/pingcap/tidb/br/pkg/storage"
-	"github.com/pingcap/tidb/br/pkg/utils"
-=======
-	"github.com/pingcap/tidb/br/pkg/gc"
->>>>>>> cb138ca3deb (br: add keyspace-aware GC safepoint support for backup and restore (`#65483`))
+	"github.com/pingcap/tidb/br/pkg/gc"
+	"github.com/pingcap/tidb/br/pkg/storage"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<<<<<<< HEAD
"github.com/pingcap/tidb/br/pkg/storage"
"github.com/pingcap/tidb/br/pkg/utils"
=======
"github.com/pingcap/tidb/br/pkg/gc"
>>>>>>> cb138ca3deb (br: add keyspace-aware GC safepoint support for backup and restore (#65483))
"github.com/pingcap/tidb/br/pkg/gc"
"github.com/pingcap/tidb/br/pkg/storage"
🧰 Tools
🪛 GitHub Check: Compile for FreeBSD job

[failure] 13-13:
missing import path

🪛 GitHub Check: Compile for macos-latest

[failure] 13-13:
missing import path

🪛 GitHub Check: Compile for ubuntu-latest

[failure] 13-13:
missing import path

🤖 Prompt for 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.

In `@br/pkg/task/common_test.go` around lines 13 - 18, Resolve the merge conflict
markers in the import block by removing the `<<<<<<<`, `=======`, and `>>>>>>>`
lines and restoring a single import list that includes both the required
packages `github.com/pingcap/tidb/br/pkg/storage` (needed for
storage.BackendOptions) and `github.com/pingcap/tidb/br/pkg/gc` (needed for
gc.DefaultBRGCSafePointTTL`), and remove `github.com/pingcap/tidb/br/pkg/utils`
if it remains and is unused in the file.

Comment thread br/pkg/task/stream.go
Comment on lines +437 to 445
func (s *streamMgr) setGCSafePoint(ctx context.Context, sp gc.BRServiceSafePoint) error {
err := gc.CheckGCSafePoint(ctx, s.mgr.GetGCManager(), sp.BackupTS)
if err != nil {
return errors.Annotatef(err,
"failed to check gc safePoint, ts %v", sp.BackupTS)
}

err = utils.UpdateServiceSafePoint(ctx, s.mgr.GetPDClient(), sp)
err = s.mgr.GetGCManager().SetServiceSafePoint(ctx, sp)
if err != nil {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use DeleteServiceSafePoint for TTL=0 removals.

This helper now always routes through SetServiceSafePoint, but RunStreamStop still uses TTL: 0 to remove the pause safepoint. That only matches the old global PD API. In keyspace mode the new manager has a separate delete path, so stop can leave the barrier behind instead of clearing it.

Suggested fix
 func (s *streamMgr) setGCSafePoint(ctx context.Context, sp gc.BRServiceSafePoint) error {
+	if sp.TTL <= 0 {
+		if err := s.mgr.GetGCManager().DeleteServiceSafePoint(ctx, sp); err != nil {
+			return errors.Trace(err)
+		}
+		log.Info("removed stream safePoint", zap.Object("safePoint", sp))
+		return nil
+	}
+
 	err := gc.CheckGCSafePoint(ctx, s.mgr.GetGCManager(), sp.BackupTS)
 	if err != nil {
 		return errors.Annotatef(err,
 			"failed to check gc safePoint, ts %v", sp.BackupTS)
 	}
🤖 Prompt for 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.

In `@br/pkg/task/stream.go` around lines 437 - 445, streamMgr.setGCSafePoint
currently always calls GetGCManager().SetServiceSafePoint which fails to remove
a safepoint when TTL==0 in keyspace mode; update setGCSafePoint to detect sp.TTL
== 0 (or the equivalent sentinel used by RunStreamStop) and call
GetGCManager().DeleteServiceSafePoint(ctx, sp) instead of SetServiceSafePoint
for removals, otherwise keep calling SetServiceSafePoint(ctx, sp); reference the
streamMgr.setGCSafePoint function and GetGCManager().DeleteServiceSafePoint /
SetServiceSafePoint methods when making the change.

Comment thread br/pkg/utils/BUILD.bazel Outdated
Comment on lines +61 to +65
<<<<<<< HEAD
"@com_github_tikv_client_go_v2//oracle",
=======
"@com_github_prometheus_client_golang//prometheus/promhttp",
>>>>>>> cb138ca3deb (br: add keyspace-aware GC safepoint support for backup and restore (#65483))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Resolve merge conflict markers before merge.

The unresolved merge conflict markers (<<<<<<< HEAD, =======, >>>>>>>) will break the Bazel build. You must choose between @com_github_tikv_client_go_v2//oracle and @com_github_prometheus_client_golang//prometheus/promhttp, or include both if both are needed by the remaining source files in this package.

🤖 Prompt for 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.

In `@br/pkg/utils/BUILD.bazel` around lines 61 - 65, Remove the unresolved git
merge markers and decide which dependency(s) should remain: either keep
"`@com_github_tikv_client_go_v2//oracle`", keep
"`@com_github_prometheus_client_golang//prometheus/promhttp`", or include both if
required by the package; specifically delete the lines starting with "<<<<<<<",
"=======", and ">>>>>>>" and update the dependency list to contain only the
correct Bazel labels so the BUILD rule is syntactically valid.

Comment thread tests/realtikvtest/brietest/BUILD.bazel Outdated
Comment on lines +19 to +22
<<<<<<< HEAD
=======
shard_count = 27,
>>>>>>> cb138ca3deb (br: add keyspace-aware GC safepoint support for backup and restore (#65483))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Resolve the leftover merge-conflict markers before merge.

Bazel will not parse this file while <<<<<<<, =======, and >>>>>>> are still present, so the brietest_test target is currently broken.

Suggested patch
-<<<<<<< HEAD
-=======
     shard_count = 27,
->>>>>>> cb138ca3deb (br: add keyspace-aware GC safepoint support for backup and restore (`#65483`))
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<<<<<<< HEAD
=======
shard_count = 27,
>>>>>>> cb138ca3deb (br: add keyspace-aware GC safepoint support for backup and restore (#65483))
shard_count = 27,
🤖 Prompt for 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.

In `@tests/realtikvtest/brietest/BUILD.bazel` around lines 19 - 22, Remove the
leftover merge-conflict markers (<<<<<<<, =======, >>>>>>>) from the BUILD.bazel
fragment and ensure the brietest_test target has the intended attribute
shard_count = 27 present; specifically, delete the conflict markers and keep the
line "shard_count = 27," inside the brietest_test target so Bazel can parse the
file cleanly.

Comment on lines +45 to +48
cfg := config.GetGlobalConfig()
cfg.Store = config.StoreTypeTiKV
cfg.Path = realtikvtest.PDAddr
config.StoreGlobalConfig(cfg)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Restore the previous global config in t.Cleanup.

config.StoreGlobalConfig mutates process-wide state. Leaving Store and Path pinned to this test's real-TiKV settings can bleed into later brietest cases and make the suite order-dependent.

Suggested patch
-	cfg := config.GetGlobalConfig()
-	cfg.Store = config.StoreTypeTiKV
-	cfg.Path = realtikvtest.PDAddr
-	config.StoreGlobalConfig(cfg)
+	prevCfg := *config.GetGlobalConfig()
+	cfg := prevCfg
+	cfg.Store = config.StoreTypeTiKV
+	cfg.Path = realtikvtest.PDAddr
+	config.StoreGlobalConfig(&cfg)
+	t.Cleanup(func() {
+		config.StoreGlobalConfig(&prevCfg)
+	})

As per coding guidelines, "Test files: Prefer extending existing test suites and fixtures over creating new scaffolding; keep test changes minimal and deterministic".

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
cfg := config.GetGlobalConfig()
cfg.Store = config.StoreTypeTiKV
cfg.Path = realtikvtest.PDAddr
config.StoreGlobalConfig(cfg)
prevCfg := *config.GetGlobalConfig()
cfg := prevCfg
cfg.Store = config.StoreTypeTiKV
cfg.Path = realtikvtest.PDAddr
config.StoreGlobalConfig(&cfg)
t.Cleanup(func() {
config.StoreGlobalConfig(&prevCfg)
})
🤖 Prompt for 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.

In `@tests/realtikvtest/brietest/gc_keyspace_test.go` around lines 45 - 48, Save
the original global config before mutating it (call config.GetGlobalConfig()
into a variable like prevCfg), then after setting cfg.Store and cfg.Path and
calling config.StoreGlobalConfig(cfg) register a t.Cleanup that restores the
original via config.StoreGlobalConfig(prevCfg); use the same variable names
(cfg, prevCfg) and t.Cleanup so the process-wide state is reverted when the test
finishes.

@tiprow

tiprow Bot commented Jun 2, 2026

Copy link
Copy Markdown

@ti-chi-bot: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
fast_test_tiprow_for_release 0cd2a74 link true /test fast_test_tiprow_for_release

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@ti-chi-bot ti-chi-bot Bot added cherry-pick-approved Cherry pick PR approved by release team. and removed do-not-merge/cherry-pick-not-approved labels Jul 31, 2026
@ti-chi-bot

Copy link
Copy Markdown
Member Author

Cherry-pick conflicts appear resolved; removing the do-not-merge/hold label.

@ti-chi-bot ti-chi-bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Aug 4, 2026
@RidRisR

RidRisR commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

/unhold

@codecov

codecov Bot commented Aug 4, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 64.06250% with 69 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (release-8.5@5dc2a71). Learn more about missing BASE report.

Additional details and impacted files
@@               Coverage Diff                @@
##             release-8.5     #68863   +/-   ##
================================================
  Coverage               ?   55.6514%           
================================================
  Files                  ?       1854           
  Lines                  ?     666894           
  Branches               ?          0           
================================================
  Hits                   ?     371136           
  Misses                 ?     268102           
  Partials               ?      27656           
Flag Coverage Δ
integration 39.1060% <41.1458%> (?)
unit 65.1166% <38.0208%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
dumpling 55.3108% <0.0000%> (?)
parser ∅ <0.0000%> (?)
br 62.5572% <0.0000%> (?)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ti-chi-bot ti-chi-bot Bot added approved needs-1-more-lgtm Indicates a PR needs 1 more LGTM. labels Aug 4, 2026
@ti-chi-bot

ti-chi-bot Bot commented Aug 4, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: Leavrth, YuJuncen

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

The pull request process is described 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 lgtm and removed needs-1-more-lgtm Indicates a PR needs 1 more LGTM. labels Aug 4, 2026
@ti-chi-bot

ti-chi-bot Bot commented Aug 4, 2026

Copy link
Copy Markdown

[LGTM Timeline notifier]

Timeline:

  • 2026-08-04 08:19:31.230095131 +0000 UTC m=+2516157.266190197: ☑️ agreed by Leavrth.
  • 2026-08-04 08:20:15.069050185 +0000 UTC m=+2516201.105145251: ☑️ agreed by YuJuncen.

@RidRisR

RidRisR commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

/test unit-test

@ti-chi-bot

ti-chi-bot Bot commented Aug 4, 2026 •

Copy link
Copy Markdown

@ti-chi-bot: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
idc-jenkins-ci-tidb/build ac9448d link true /test build

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@ti-chi-bot ti-chi-bot Bot removed the cherry-pick-approved Cherry pick PR approved by release team. label Aug 4, 2026
@ti-chi-bot ti-chi-bot Bot closed this Aug 4, 2026
@ti-chi-bot

ti-chi-bot Bot commented Aug 4, 2026

Copy link
Copy Markdown

This cherry pick PR is for a release branch and has not yet been approved by triage owners.
Adding the do-not-merge/cherry-pick-not-approved label.

To merge this cherry pick:

  1. It must be LGTMed and approved by the reviewers firstly.
  2. For pull requests to TiDB-x branches, it must have no failed tests.
  3. AFTER it has lgtm and approved labels, please wait for the cherry-pick merging approval from triage owners.
Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@coderabbitai coderabbitai Bot mentioned this pull request Aug 7, 2026
1 of 9 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved do-not-merge/cherry-pick-not-approved lgtm ok-to-test Indicates a PR is ready to be tested. 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. type/cherry-pick-for-release-8.5 This PR is cherry-picked to release-8.5 from a source PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants