Skip to content

br, pkg/objstore: add operation metadata to external storage locks - #69231

Merged
ti-chi-bot[bot] merged 27 commits into
pingcap:masterfrom
RidRisR:br-lock-operation-id-design
Jun 23, 2026
Merged

ti-chi-bot[bot] merged 27 commits into
pingcap:masterfrom
RidRisR:br-lock-operation-id-design

Conversation

@RidRisR

@RidRisR RidRisR commented Jun 16, 2026 •

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: ref #67819

Problem Summary:

BR external-storage lock files are permanent until removed. When a BR process crashes or gets stuck, operators need enough metadata in the lock file and conflict logs to identify which BR execution created or is blocked by a lock.

What changed and how does it work?

This PR adds operation-aware metadata for BR-created external-storage locks:

  • Add structured lock metadata support in pkg/objstore, including operation_id, operation_started_at, restore_id, and resource_type.
  • Add br/pkg/operation to generate one command-scoped operation ID, log it at command start, attach restore ID when available, and build validated lock metadata.
  • Add operation-aware lock wrappers for BR code so production lock creators pass operation context and resource type explicitly.
  • Propagate operation context through log restore, stream truncate, migration read/write/append locks, log client migration reads, PITR collector append migration, and operator migrate-to.
  • Enrich lock conflict errors and retry/direct conflict logs with local operation metadata and remote blocker metadata.

Check List

Tests

  • Unit test
  • Integration test
  • Manual test (add detailed scripts or steps below)
  • No need to test
    • I checked and no code files have been changed.

Manual test commands:

env GOCACHE=/tmp/tidb-gocache go test ./br/pkg/operation
env GOCACHE=/tmp/tidb-gocache ./tools/check/failpoint-go-test.sh pkg/objstore -run 'Test(MakeLockMeta|LockMeta|ConflictLockReports|WriteLockConflictReports|LockWithRetryCarries|TryLockRemoteWritePreserves)' -count=1
env GOCACHE=/tmp/tidb-gocache ./tools/check/failpoint-go-test.sh pkg/objstore -run 'Test(LockConflictLogFieldsCarriesLocalAndRemoteMetadata|LockWithRetryCarriesLocalAndRemoteMetadata|ConflictLockReportsRemotePathAndMeta|WriteLockConflictReportsReadLockBlocker|TryLockRemoteWritePreservesOriginalErrorWhenEnrichingErrLocked)' -count=1
env GOCACHE=/tmp/tidb-gocache ./tools/check/failpoint-go-test.sh pkg/objstore/s3store -run 'TestTryLockRemoteRootPathPrefix' -count=1
env GOCACHE=/tmp/tidb-gocache ./tools/check/failpoint-go-test.sh br/pkg/stream -run 'Test(MigrationLockOperationMetadata|MigrationExtDryRunKeepsOperationContext|MergeAndMigrateToMissingOperationContextReturnsError|MergeAndMigrateTo|AppendingMigs)$' -count=1
env GOCACHE=/tmp/tidb-gocache ./tools/check/failpoint-go-test.sh br/pkg/restore/log_client -run 'TestGetLockedMigrationsWritesOperationMetadata' -count=1
env GOCACHE=/tmp/tidb-gocache ./tools/check/failpoint-go-test.sh br/pkg/restore/snap_client -run 'TestPiTRCollectorPrepareMigWritesOperationMetadata' -count=1
env GOCACHE=/tmp/tidb-gocache go test ./br/pkg/task/operator
env GOCACHE=/tmp/tidb-gocache go build ./br/pkg/task ./br/pkg/task/operator ./br/pkg/restore/log_client ./br/pkg/restore/snap_client
make bazel_prepare
make lint
git diff --check

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

Please refer to Release Notes Language Style Guide to write a quality release note.

None

Summary by CodeRabbit

Release Notes

  • New Features
    • Lock activity is now correlated end-to-end using per-operation identifiers (including restore IDs) across restore, stream truncate, and migration locking.
    • Remote lock acquisition and retries now persist this operation-aware lock metadata.
  • Bug Fixes
    • Lock conflict errors and related log fields are more structured, with clearer blocker and operation-context detail.
  • Documentation
    • Added guidance defining the terminology and propagation rules for external-storage lock metadata.
  • Tests
    • Expanded coverage to verify operation-context propagation and persisted lock metadata across restore, stream, and migration flows.

@ti-chi-bot

ti-chi-bot Bot commented Jun 16, 2026

Copy link
Copy Markdown

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@ti-chi-bot ti-chi-bot Bot added release-note-none Denotes a PR that doesn't merit a release note. do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. needs-cherry-pick-release-8.5 Should cherry pick this PR to release-8.5 branch. labels Jun 16, 2026
@coderabbitai

coderabbitai Bot commented Jun 16, 2026 •

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Introduces operation-scoped lock metadata for BR external-storage locks. A new operation package provides Context (UUID-based operation identity, restore ID, log deduplication) and operation-aware lock wrappers. The objstore locking APIs are refactored from plain string hints to structured LockMetaInput, with enriched ErrLocked carrying local metadata and blocker details. Operation context is propagated through MigrationExt, LogClient, PiTRCollDep, and all BR task entry points.

Changes

Operation-scoped lock metadata and BR integration

Layer / File(s) Summary
Terminology and design contracts
CONTEXT.md, docs/design/2026-06-15-br-external-storage-lock-owner.md
Defines BR lock terminology (Operation, OperationID, RestoreID, LockResource, etc.) and a comprehensive design document specifying lock metadata schema, propagation rules, logging requirements, compatibility constraints, and future work.
objstore LockMetaInput and enriched conflict plumbing
pkg/objstore/locking.go, pkg/objstore/locking_test.go, pkg/objstore/BUILD.bazel, pkg/objstore/s3store/s3_test.go
Replaces hint string with LockMetaInput across TryLockRemote*, LockWithRetry, and Locker; expands LockMeta and ErrLocked with operation/restore/resource fields and blocker lists; adds MakeLockMeta, LockConflictLogFields, conflict-collection and error-enrichment helpers; updates all tests for the new API and adds backward-compatibility JSON tests.
br/pkg/operation context and lock wrappers
br/pkg/operation/context.go, br/pkg/operation/lock.go, br/pkg/operation/context_test.go, br/pkg/operation/BUILD.bazel
New package: Context with UUID-based OperationID, StartedAt, RestoreID, mutex-protected restore-ID log deduplication, and LockMeta metadata builder; LockResourceType constants; LockMetadataError; operation-aware wrappers (TryLockRemote*, LockWithRetry*, LockConflictLogFields) over objstore primitives; full unit and integration tests.
MigrationExt operation-context locking and API return updates
br/pkg/stream/stream_metas.go, br/pkg/stream/stream_metas_test.go, br/pkg/stream/BUILD.bazel
Adds WithOperationContext to MigrationExt; switches GetReadLock, lockForAppend, and MergeAndMigrateTo to operation-aware lock wrappers; changes MergeAndMigrateTo signature to return (result, error); propagates operationContext through DryRun; aligns all callers and tests with new conventions and adds lock-metadata capture assertions.
LogClient and PiTR collector operation-context propagation
br/pkg/restore/log_client/client.go, br/pkg/restore/log_client/client_test.go, br/pkg/restore/log_client/BUILD.bazel, br/pkg/restore/snap_client/pitr_collector.go, br/pkg/restore/snap_client/pitr_collector_test.go, br/pkg/restore/snap_client/BUILD.bazel
Adds operationContext to LogClient with bidirectional restore-ID sync and wires it into GetLockedMigrations; adds OperationContext to PiTRCollDep and pitrCollector with wiring through newPiTRColl and prepareMig; adds storage-level lock-meta assertions in new tests.
Task config and command entrypoint wiring
br/pkg/task/common.go, br/pkg/task/restore.go, br/pkg/task/stream.go, br/pkg/task/operator/migrate_to.go, br/pkg/task/BUILD.bazel, br/pkg/task/operator/BUILD.bazel
Adds OperationContext operation.Context and EnsureOperationContext to task.Config; calls EnsureOperationContext at the start of RunRestore, RunRestoreAbort, RunStreamTruncate, and RunStreamRestore; propagates restore ID into cfg.OperationContext post-registration; updates RunMigrateTo dry-run callbacks for the new (result, error) estimator signature; updates all Bazel BUILD files.

Sequence Diagram(s)

sequenceDiagram
  participant TaskEntry as RunStreamTruncate / RunStreamRestore
  participant Config as task.Config
  participant OpCtx as operation.Context
  participant OpLock as operation.TryLockRemote / LockWithRetry*
  participant MigExt as MigrationExt
  participant ObjStore as objstore.TryLockRemote* / LockWithRetry

  TaskEntry->>Config: EnsureOperationContext(cmdName)
  Config->>OpCtx: Ensure(cmdName) → generates UUID OperationID, StartedAt
  TaskEntry->>OpCtx: SetRestoreID(resolvedRestoreID)
  TaskEntry->>OpLock: TryLockRemote(storage, path, opCtx, resource, hint)
  OpLock->>OpCtx: LockMeta(resource, hint) → LockMetaInput
  OpLock->>ObjStore: TryLockRemote(path, LockMetaInput)
  ObjStore-->>OpLock: RemoteLock or ErrLocked{Path, Local, Blockers}
  OpLock-->>TaskEntry: RemoteLock or error
  TaskEntry->>MigExt: WithOperationContext(opCtx)
  MigExt->>OpLock: LockWithRetryWrite(path, opCtx, resource, hint)
  OpLock->>ObjStore: LockWithRetry(locker, path, LockMetaInput)
  ObjStore-->>OpLock: RemoteLock or enriched ErrLocked
  MigExt-->>TaskEntry: MergeAndMigratedTo, error
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

  • pingcap/tidb#67850: Both PRs touch the migration lock plumbing in the same restoration/stream codepaths—main PR propagates operation.Context into LogClient.GetLockedMigrations-acquired lock metadata, while the retrieved PR fixes a GetLockedMigrations read-lock leak on Load() error.
  • pingcap/tidb#69059: Both PRs modify br/pkg/restore/log_client/client.go's LogClient.GetLockedMigrations (main PR adds operation-context propagation into the migration extension/lock flow, while retrieved PR changes the method to ensure the migration read lock is released on load errors).

Suggested reviewers

  • YuJuncen

🐇 A UUID is born with each BR command I run,
Lock files now know who put them there — isn't that fun?
OperationID, StartedAt, and RestoreID too,
Conflict logs bloom with rich metadata clues!
No more mystery locks left to rue~ ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.91% 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 'br, pkg/objstore: add operation metadata to external storage locks' clearly and concisely summarizes the main change: adding operation metadata to external storage locks across multiple packages.
Description check ✅ Passed The PR description includes the required issue reference (ref #67819), a clear problem summary, detailed explanation of changes, comprehensive test coverage documentation, and explicit answers to all checklist items.
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.

@ti-chi-bot ti-chi-bot Bot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label Jun 16, 2026
@tiprow

tiprow Bot commented Jun 16, 2026

Copy link
Copy Markdown

Hi @RidRisR. Thanks for your PR.

PRs from untrusted users cannot be marked as trusted with /ok-to-test in this repo meaning untrusted PR authors can never trigger tests themselves. Collaborators can still trigger tests on the PR using /test all.

I understand the commands that are listed here.

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.

@RidRisR
RidRisR requested review from Leavrth and YuJuncen and removed request for YuJuncen June 16, 2026 07:46
@RidRisR
RidRisR marked this pull request as ready for review June 16, 2026 07:47
@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 Jun 16, 2026
@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{}

@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: 1

🤖 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 `@pkg/objstore/locking.go`:
- Around line 151-160: The unbounded blocker hydration in the callback function
where blockers are appended via lockBlockerFromPath causes poor scaling under
heavy contention. Cap the number of blockers that are hydrated and parsed to a
fixed limit (e.g., first N), maintain a separate counter for the total blocker
count, and apply this cap at all locations where blockers are collected
(including the WalkDir callback). Modify the blocker-appending logic to stop
hydrating blockers after reaching the limit while continuing to count total
blockers, then serialize and log only the sampled blockers while reporting the
total blocker count separately in error messages and logs.
🪄 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: e95fb8d4-b429-4129-82de-2c2973e150d3

📥 Commits

Reviewing files that changed from the base of the PR and between 3adc8ec and 2b94949.

📒 Files selected for processing (25)
  • CONTEXT.md
  • br/pkg/operation/BUILD.bazel
  • br/pkg/operation/context.go
  • br/pkg/operation/context_test.go
  • br/pkg/operation/lock.go
  • br/pkg/restore/log_client/BUILD.bazel
  • br/pkg/restore/log_client/client.go
  • br/pkg/restore/log_client/client_test.go
  • br/pkg/restore/snap_client/BUILD.bazel
  • br/pkg/restore/snap_client/pitr_collector.go
  • br/pkg/restore/snap_client/pitr_collector_test.go
  • br/pkg/stream/BUILD.bazel
  • br/pkg/stream/stream_metas.go
  • br/pkg/stream/stream_metas_test.go
  • br/pkg/task/BUILD.bazel
  • br/pkg/task/common.go
  • br/pkg/task/operator/BUILD.bazel
  • br/pkg/task/operator/migrate_to.go
  • br/pkg/task/restore.go
  • br/pkg/task/stream.go
  • docs/design/2026-06-15-br-external-storage-lock-owner.md
  • pkg/objstore/BUILD.bazel
  • pkg/objstore/locking.go
  • pkg/objstore/locking_test.go
  • pkg/objstore/s3store/s3_test.go

Comment thread pkg/objstore/locking.go
@codecov

codecov Bot commented Jun 16, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 23.04440% with 364 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.8434%. Comparing base (0744e84) to head (e9b7fff).
⚠️ Report is 2 commits behind head on master.

Additional details and impacted files
@@               Coverage Diff                @@
##             master     #69231        +/-   ##
================================================
- Coverage   76.3198%   75.8434%   -0.4764%     
================================================
  Files          2041       2058        +17     
  Lines        561423     573303     +11880     
================================================
+ Hits         428477     434813      +6336     
- Misses       132043     137196      +5153     
- Partials        903       1294       +391     
Flag Coverage Δ
integration 44.6835% <23.0444%> (+5.0701%) ⬆️

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

Components Coverage Δ
dumpling 60.4610% <ø> (ø)
parser ∅ <ø> (∅)
br 64.7573% <48.6607%> (+1.9324%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread pkg/objstore/locking.go Outdated
Comment thread pkg/objstore/locking.go Outdated
Comment thread pkg/objstore/locking.go Outdated
Path string
Meta LockMeta
Local LockMetaInput
Blockers []LockBlocker

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It seems blockers can replace Meta.

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.

I kept Meta intentionally as the primary/compatibility summary. Blockers is the newer detailed list, but Meta was the existing ErrLocked payload and is still useful when there is a single known lock or when older call paths enrich only one remote lock. When blockers are available, enrichErrLocked fills Meta from the first blocker, so consumers can use either the summary or the detailed list.

Comment thread br/pkg/operation/context.go Outdated
Comment on lines +131 to +139
if c.OperationID == "" {
return objstore.LockMetaInput{}, errors.New("operation ID is required")
}
if c.StartedAt.IsZero() {
return objstore.LockMetaInput{}, errors.New("operation started time is required")
}
if resource == "" {
return objstore.LockMetaInput{}, errors.New("lock resource type is required")
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

These fields can be lazily initialized when not found. resource can be an enum to avoid empty.

@RidRisR RidRisR Jun 16, 2026 •

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.

Kept explicit validation here. I believe it is necessary for data integrity.

Comment thread br/pkg/operation/context.go Outdated
Comment thread br/pkg/operation/context.go
@ti-chi-bot ti-chi-bot Bot added approved needs-1-more-lgtm Indicates a PR needs 1 more LGTM. labels Jun 18, 2026

@YuJuncen YuJuncen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

rest lgtm

Comment on lines +34 to +35
type Context struct {
OperationID string `json:"operation_id"`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

From the call sites in this PR, OperationID and StartedAt are initialized at the command boundary and then only read/copied into lock metadata. They do not appear to need later state transitions. Consider modeling these fields as a config/value snapshot fixed when Context is created, instead of allowing lower layers to lazily initialize the operation identity through Ensure. The only late-bound field here seems to be RestoreID, which can keep an explicit update path. This would make the ownership clearer: the command boundary allocates the operation identity, and storage locking only consumes already-initialized metadata.

Comment thread pkg/objstore/locking.go
// LockMetaInput is the caller-provided metadata for a lock.
type LockMetaInput struct {
OwnerID string
LockType string

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LockType may be easy to misread as the lock algorithm's read/write/exclusive mode, but from the current usage it is metadata describing the higher-level BR resource/scope, such as migration read/write/append or log-truncate-exclusive. Could we add a comment that explains this scope, and maybe use a more precise name such as ResourceType or LockResource? That would make it clearer that conflict behavior is still determined by the lock paths and read/write helpers, not by this metadata field.

Comment thread br/pkg/operation/context.go Outdated
type Context struct {
OperationID string `json:"operation_id"`
StartedAt time.Time `json:"operation_started_at"`
RestoreID uint64 `json:"restore_id,omitempty"`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

RestoreID makes this otherwise generic operation context depend on restore-specific lineage. That feels a bit surprising for a neutral package that is also used by stream migration/operator paths. Could we model this as neutral structured metadata instead, for example a small set of extra lock/log fields similar to []zap.Field, and let the restore layer add restore_id there? Then operation.Context would stay focused on command identity, while restore-specific metadata remains owned by the restore layer.

@YuJuncen YuJuncen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

rest lgtm

Comment on lines 140 to 144
if c.OperationID == "" {
return objstore.LockMetaInput{}, errors.New("operation ID is required")
}
if c.StartedAt.IsZero() {
return objstore.LockMetaInput{}, errors.New("operation started time is required")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Given they are assigned when creating, they are almost impossible to be zero.

Comment thread br/pkg/operation/context.go Outdated
Comment on lines +35 to +37
OperationID string `json:"operation_id"`
StartedAt time.Time `json:"operation_started_at"`
HintFields []HintField `json:"hint_fields,omitempty"`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Are we still need to serialize Context? If not, better to remove the json annotations.
Also HintFields can better be a map.

@ti-chi-bot

ti-chi-bot Bot commented Jun 23, 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 Jun 23, 2026
@ti-chi-bot

ti-chi-bot Bot commented Jun 23, 2026

Copy link
Copy Markdown

[LGTM Timeline notifier]

Timeline:

  • 2026-06-18 13:05:58.857973922 +0000 UTC m=+1656459.928291312: ☑️ agreed by Leavrth.
  • 2026-06-23 06:04:17.143419138 +0000 UTC m=+13940.806644651: ☑️ agreed by YuJuncen.

@RidRisR
RidRisR force-pushed the br-lock-operation-id-design branch from f728183 to e9b7fff Compare June 23, 2026 06:23
@ti-chi-bot
ti-chi-bot Bot merged commit 807326b into pingcap:master Jun 23, 2026
35 checks passed
@ti-chi-bot

Copy link
Copy Markdown
Member

In response to a cherrypick label: new pull request created to branch release-8.5: #69388.
But this PR has conflicts, please resolve them!

@ti-chi-bot ti-chi-bot Bot removed the needs-cherry-pick-release-8.5 Should cherry pick this PR to release-8.5 branch. label Jun 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved lgtm 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.

4 participants