Skip to content

br: support restore privileges tables from v6.5 to v7.5 (#64668) - #70432

Open
ti-chi-bot wants to merge 1 commit into
pingcap:release-8.1from
ti-chi-bot:cherry-pick-64668-to-release-8.1
Open

ti-chi-bot wants to merge 1 commit into
pingcap:release-8.1from
ti-chi-bot:cherry-pick-64668-to-release-8.1

Conversation

@ti-chi-bot

@ti-chi-bot ti-chi-bot commented Aug 11, 2026 •

Copy link
Copy Markdown
Member

This is an automated cherry-pick of #64668

What problem does this PR solve?

Issue Number: close #64667

Problem Summary:
It is needed to restore privileges tables backed up from v6.5 to newly created v7.2+ clusters.

What changed and how does it work?

permit to restore privileges tables from v6.5 to v7.2+ if all the data have the same behavior in utf8mb4_bin and utf8mb4_general_ci.

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.

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

  • New Features

    • Added comprehensive snapshot restore support, including full, incremental, checkpointed, raw-KV, and transactional restores.
    • Added restoration of databases, tables, schemas, placement policies, DDL, statistics, and system metadata.
    • Added restore controls for rate limits, concurrency, encryption, rewrite mode, and point-in-time recovery.
  • Bug Fixes

    • Added system-table compatibility checks, including collation validation and privilege-table safeguards.
    • Added fallback handling when physical system-table restoration is incompatible.
  • Configuration

    • Added the sys-check-collation restore option.

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.1 This PR is cherry-picked to release-8.1 from a source PR. labels Aug 11, 2026
@ti-chi-bot

ti-chi-bot Bot commented Aug 11, 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.

@ti-chi-bot

ti-chi-bot Bot commented Aug 11, 2026

Copy link
Copy Markdown

[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 leavrth 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

Copy link
Copy Markdown
Member Author

@Leavrth 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 Aug 11, 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 Aug 11, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a SnapClient for snapshot restore orchestration, system-schema restoration, privilege-table collation validation, restore configuration, checksum handling, test helpers, and Bazel targets. It also changes IsTypeCompatible to return separate type and collation results.

Changes

Snapshot restore client

Layer / File(s) Summary
Restore client lifecycle and importer setup
br/pkg/restore/snap_client/client.go
Adds checkpoint handling, importer initialization, restore configuration, metadata access, store rate limiting, and PD/TiKV integration.
Database, table, and checksum restore
br/pkg/restore/snap_client/client.go
Adds concurrent database and table creation, rewrite rules, restore-mode checks, DDL execution, and checksum validation.
System-schema restoration and privilege compatibility
br/pkg/restore/snap_client/systable_restore.go, br/pkg/restore/snap_client/systable_restore_test.go, br/pkg/restore/snap_client/export_test.go
Adds system-schema replacement, temporary-table handling, statistics migrations, privilege-row validation, cleanup, and related tests and helpers.
Restore options and type compatibility contract
br/pkg/task/restore.go, br/pkg/utils/misc.go, br/pkg/utils/misc_test.go
Adds sys-check-collation, wires compatibility checks into full-cluster restore, and separates type compatibility from collation equality. The changed restore file contains unresolved merge-conflict markers.
Bazel build and test targets
br/pkg/restore/snap_client/BUILD.bazel
Adds the snap_client library and its short, flaky, 42-shard test target.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant RestoreTask
  participant SnapClient
  participant TargetSQL
  participant PrivilegeNotifier
  RestoreTask->>SnapClient: check system-table compatibility
  SnapClient->>TargetSQL: inspect schemas and privilege rows
  SnapClient->>TargetSQL: replace or rename system tables
  SnapClient->>PrivilegeNotifier: flush updated privileges
  SnapClient-->>RestoreTask: complete system-schema restore
Loading

Possibly related PRs

Suggested labels: needs-rebase

Suggested reviewers: yujuncen, ridrisr

Poem

I hop through snapshots, tidy and bright,
Restore each table in schema-right light.
Collations align, privileges flow,
Checksums confirm what the bytes should show.
Bazel builds while my ears stand tall—
A careful restore for one and all.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% 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 identifies the BR restore change and the supported version range.
Description check ✅ Passed The description includes the issue, problem, implementation, tests, side effects, documentation, and release note sections.
Linked Issues check ✅ Passed The changes add collation-aware compatibility checks and privilege-table restore logic for the v6.5-to-v7.5 scenario in issue #64667.
Out of Scope Changes check ✅ Passed The listed build, client, system-schema, configuration, utility, and test changes support the linked privilege-table restore objective.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 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.

@ti-chi-bot

ti-chi-bot Bot commented Aug 11, 2026

Copy link
Copy Markdown

@ti-chi-bot: The following tests 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 a504628 link true /test build
idc-jenkins-ci-tidb/check_dev a504628 link true /test check-dev
idc-jenkins-ci-tidb/check_dev_2 a504628 link true /test check-dev2
idc-jenkins-ci-tidb/unit-test a504628 link true /test unit-test
idc-jenkins-ci-tidb/mysql-test a504628 link true /test mysql-test

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.

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

🧹 Nitpick comments (5)
br/pkg/restore/snap_client/systable_restore_test.go (1)

110-112: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Remove the commented-out line and clone consistently.

Line 111 is dead code. Line 112 appends to dbTI.Columns and assigns the result to mockedDBTI.Columns, which mixes the two table infos. Use mockedDBTI.Columns on both sides to keep the clone independent.

♻️ Proposed cleanup
 	mockedDBTI := dbTI.Clone()
-	//dbTI.Columns = append(dbTI.Columns, &model.ColumnInfo{Name: ast.NewCIStr("new-name")})
-	mockedDBTI.Columns = append(dbTI.Columns, &model.ColumnInfo{Name: ast.NewCIStr("new-name")})
+	mockedDBTI.Columns = append(mockedDBTI.Columns, &model.ColumnInfo{Name: ast.NewCIStr("new-name")})
🤖 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/snap_client/systable_restore_test.go` around lines 110 - 112,
In the test setup around mockedDBTI, remove the commented-out append and update
the active append to use mockedDBTI.Columns as both the source and destination,
preserving the cloned dbTI independently.
br/pkg/utils/misc.go (1)

60-61: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a doc comment that explains the two results.

IsTypeCompatible is exported and now returns two booleans with different meanings. typeEq covers flags, evaluation type, length, decimal, elements, and charset. collateEq covers only the collation. A caller cannot infer this split from the signature.

📝 Proposed comment
+// IsTypeCompatible reports whether the target field type can hold the source
+// field type. typeEq covers nullability, sign, evaluation type, length,
+// decimal, enum/set elements, and charset. collateEq reports collation
+// equality separately, so callers can accept a collation-only difference.
 func IsTypeCompatible(src types.FieldType, target types.FieldType) (typeEq, collateEq bool) {

As per coding guidelines: "keep exported-symbol doc comments".

🤖 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/misc.go` around lines 60 - 61, Add a Go doc comment directly
above the exported IsTypeCompatible function explaining that typeEq compares
flags, evaluation type, length, decimal, elements, and charset, while collateEq
compares only collation.

Source: Coding guidelines

br/pkg/task/restore.go (1)

285-286: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Document the risk of sys-check-collation in the flag help text.

The flag permits a restore that would otherwise be rejected. The current text describes the mechanism but not the consequence. State that BR aborts the restore if the privilege rows collide under utf8mb4_general_ci, so operators understand the failure mode before they enable the flag.

Also confirm whether this flag should stay visible or use flags.MarkHidden, as other compatibility flags in DefineRestoreCommonFlags do.

🤖 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/restore.go` around lines 285 - 286, Update the
FlagSysCheckCollation help text in DefineRestoreCommonFlags to state that BR
aborts the restore when privilege rows collide under utf8mb4_general_ci, in
addition to describing the collation conversion. Review the surrounding
compatibility flags and apply flags.MarkHidden if this flag should follow their
visibility convention.
br/pkg/restore/snap_client/systable_restore.go (1)

154-172: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider deriving the temporary schema name instead of hardcoding it.

The SQL strings embed __TiDB_BR_Temporary_mysql. The rest of the package builds this name with utils.TemporaryDBName(dbName). If the prefix changes, these literals silently break the check because the SQL then targets a missing table.

Building the SQL from utils.TemporaryDBName at call time keeps one source of truth.

🤖 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/snap_client/systable_restore.go` around lines 154 - 172,
Update the collate compatibility SQL construction around
collateCompatibilityTables to derive the temporary schema with
utils.TemporaryDBName(dbName) at call time instead of embedding
__TiDB_BR_Temporary_mysql in static literals. Preserve the existing queries and
column mappings while ensuring all referenced tables use the generated schema
name.
br/pkg/restore/snap_client/export_test.go (1)

84-100: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

AllocTableIDs runs twice with the same arguments.

Line 90 and line 99 make the same call. The first call also discards its return value. Remove the duplicate call.

♻️ Proposed cleanup
 	rc.dom = dom
-	rc.AllocTableIDs(context.TODO(), tables, false, false, nil)
 	rewriteRules := &restoreutils.RewriteRules{
 		Data: make([]*import_sstpb.RewriteRule, 0),
 	}

Confirm that AllocTableIDs returns no error that the helper must handle.

🤖 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/snap_client/export_test.go` around lines 84 - 100, Remove the
redundant first AllocTableIDs call in CreateTablesTest, keeping the later
invocation before CreateTables. Confirm AllocTableIDs has no error result
requiring handling, and preserve the existing table-mapping and creation flow.
🤖 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/restore/snap_client/client.go`:
- Around line 276-286: Resolve the merge conflicts in restore.go by removing all
unresolved conflict markers at the specified sections and retaining the correct
merged implementation for each block. Preserve the existing restore-flag wiring
through SnapClient.SetCheckPrivilegeTableRowsCollateCompatiblity and
GetCheckPrivilegeTableRowsCollateCompatiblity, ensuring the file compiles.

In `@br/pkg/restore/snap_client/export_test.go`:
- Around line 65-73: Update the callback registration in the test setup so the
close callback is appended to closeCallBacks rather than createCallBacks. Keep
createCallBacks containing only the rate-limit initialization callback, ensuring
close execution invokes only the callback that resets the rate limit.

In `@br/pkg/restore/snap_client/systable_restore_test.go`:
- Around line 137-145: Update the type-mismatch setup in the test around
CheckSysTableCompatibility to mutate the same table info that is passed to it:
change the relevant column on mockedDBTI rather than mockedUserTI. Preserve the
expected no-error assertion for this case, confirming the collate difference
remains skipped while the DB column type mismatch is exercised.
- Around line 395-397: Update TestMonitorTheSystemTableIncremental to assert
session.CurrentBootstrapVersion equals the release-8.1 branch value version199
instead of 253.

In `@br/pkg/restore/snap_client/systable_restore.go`:
- Around line 807-811: Update the error message in the colCount validation
branch to report utf8mb4_general_ci instead of utf8mb4_bin, keeping the existing
error type, formatting, and control flow unchanged.

In `@br/pkg/task/restore.go`:
- Around line 279-287: Resolve every merge conflict marker in
br/pkg/task/restore.go, including the blocks around flag registration, restore
client setup, and physical system-table loading. In the restore setup, retain
restore.CheckKeyspaceBREnable, client.LoadRestoreStores(ctx), and
client.SetConcurrency(uint(cfg.Concurrency)) together with SetRewriteMode(ctx)
and SetCheckPrivilegeTableRowsCollateCompatiblity(cfg.SysCheckCollation),
confirming SnapClient.SetRewriteMode exists. Ensure the retained branch declares
canLoadSysTablePhysical and err before the subsequent error handling and
fallback, and preserve or intentionally remove the code hidden near line 828.

In `@br/pkg/utils/misc_test.go`:
- Around line 81-83: Update the test case around IsTypeCompatible so the target
column’s length is explicitly smaller than the source length, rather than
assigning 99 to its flag field. Preserve the existing assertions and ensure the
inputs reach the length-comparison branch instead of returning early on flag
incompatibility.

In `@br/pkg/utils/misc.go`:
- Around line 60-70: Update the IsTypeCompatible call in the restore client
type-checking logic to receive both returned values, using the typeEq result for
the existing compatibility decision and handling collateEq as required by the
surrounding logic. Ensure the call no longer treats the two-value return as a
single boolean and compiles successfully.

---

Nitpick comments:
In `@br/pkg/restore/snap_client/export_test.go`:
- Around line 84-100: Remove the redundant first AllocTableIDs call in
CreateTablesTest, keeping the later invocation before CreateTables. Confirm
AllocTableIDs has no error result requiring handling, and preserve the existing
table-mapping and creation flow.

In `@br/pkg/restore/snap_client/systable_restore_test.go`:
- Around line 110-112: In the test setup around mockedDBTI, remove the
commented-out append and update the active append to use mockedDBTI.Columns as
both the source and destination, preserving the cloned dbTI independently.

In `@br/pkg/restore/snap_client/systable_restore.go`:
- Around line 154-172: Update the collate compatibility SQL construction around
collateCompatibilityTables to derive the temporary schema with
utils.TemporaryDBName(dbName) at call time instead of embedding
__TiDB_BR_Temporary_mysql in static literals. Preserve the existing queries and
column mappings while ensuring all referenced tables use the generated schema
name.

In `@br/pkg/task/restore.go`:
- Around line 285-286: Update the FlagSysCheckCollation help text in
DefineRestoreCommonFlags to state that BR aborts the restore when privilege rows
collide under utf8mb4_general_ci, in addition to describing the collation
conversion. Review the surrounding compatibility flags and apply
flags.MarkHidden if this flag should follow their visibility convention.

In `@br/pkg/utils/misc.go`:
- Around line 60-61: Add a Go doc comment directly above the exported
IsTypeCompatible function explaining that typeEq compares flags, evaluation
type, length, decimal, elements, and charset, while collateEq compares only
collation.
🪄 Autofix

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 Plus

Run ID: e792b7d8-2187-4f50-b9dd-522419903048

📥 Commits

Reviewing files that changed from the base of the PR and between 986af29 and a504628.

📒 Files selected for processing (8)
  • br/pkg/restore/snap_client/BUILD.bazel
  • br/pkg/restore/snap_client/client.go
  • br/pkg/restore/snap_client/export_test.go
  • br/pkg/restore/snap_client/systable_restore.go
  • br/pkg/restore/snap_client/systable_restore_test.go
  • br/pkg/task/restore.go
  • br/pkg/utils/misc.go
  • br/pkg/utils/misc_test.go

Comment on lines +276 to +286
// SetCheckPrivilegeTableRowsCollateCompatiblity set switch to check
// privilege tables with different collate columns
func (rc *SnapClient) SetCheckPrivilegeTableRowsCollateCompatiblity(v bool) {
rc.checkPrivilegeTableRowsCollateCompatiblity = v
}

// GetCheckPrivilegeTableRowsCollateCompatiblity get switch to check
// privilege tables with different collate columns
func (rc *SnapClient) GetCheckPrivilegeTableRowsCollateCompatiblity() bool {
return rc.checkPrivilegeTableRowsCollateCompatiblity
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Confirm the setter and getter for the privilege-table collation flag are wired across the codebase.

# Find every reference to the setter, getter, and backing field.
rg -nP -C4 '(Set|Get)?CheckPrivilegeTableRowsCollateCompatiblity' --type=go

# Confirm the systable restore path consumes the getter near the privilege-table check.
fd -t f 'systable_restore.go' --exec rg -nP -C6 'CollateCompatiblity|REPLACE INTO|utf8mb4_general_ci|utf8mb4_bin' {}

# Confirm the task layer sets the flag from the restore config.
fd -t f 'restore.go' -p 'br/pkg/task' --exec rg -nP -C6 'CollateCompatiblity' {}

Repository: pingcap/tidb

Length of output: 150


🏁 Script executed:

#!/bin/bash
set -u

printf '%s\n' '--- candidate files ---'
git ls-files | rg '(^|/)(client|systable_restore|restore)\.go$' | head -80

printf '%s\n' '--- all compatibility spellings and related symbols ---'
rg -n -P -C3 'CheckPrivilegeTableRowsCollate(?:Compatiblity|Compatibility)|CollateCompatiblity|CollateCompatibility' --glob '*.go' . || true

printf '%s\n' '--- privilege-table restore references ---'
rg -n -P -C5 'privilege|Privilege|collate|Collate' br/pkg/restore/snap_client br/pkg/task/restore.go --glob '*.go' | head -300 || true

Repository: pingcap/tidb

Length of output: 43562


🏁 Script executed:

#!/bin/bash
python3 - <<'PY'
from pathlib import Path
import re

files = [
    Path("br/pkg/restore/snap_client/client.go"),
    Path("br/pkg/restore/snap_client/systable_restore.go"),
    Path("br/pkg/task/restore.go"),
]

symbols = [
    "SetCheckPrivilegeTableRowsCollateCompatiblity",
    "GetCheckPrivilegeTableRowsCollateCompatiblity",
]

for path in files:
    text = path.read_text()
    print(f"--- {path} ---")
    for symbol in symbols:
        matches = [(i, line) for i, line in enumerate(text.splitlines(), 1)
                   if symbol in line]
        print(f"{symbol}: {len(matches)} occurrence(s)")
        for line_no, line in matches:
            print(f"  {line_no}: {line.strip()}")

    markers = [(i, line) for i, line in enumerate(text.splitlines(), 1)
               if re.match(r"^\s*(<<<<<<<|=======|>>>>>>>)(?:\s|$)", line)]
    if markers:
        print("merge conflict markers:")
        for line_no, line in markers:
            print(f"  {line_no}: {line.strip()}")
PY

printf '%s\n' '--- restore.go surrounding the flag wiring ---'
sed -n '565,590p;870,895p' br/pkg/task/restore.go

Repository: pingcap/tidb

Length of output: 3861


Resolve the merge conflicts in br/pkg/task/restore.go.

The restore flag is wired correctly. Remove the unresolved <<<<<<<, =======, and >>>>>>> markers at lines 279-287, 408-418, 564-582, and 828-887 because they prevent compilation.

🤖 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/snap_client/client.go` around lines 276 - 286, Resolve the
merge conflicts in restore.go by removing all unresolved conflict markers at the
specified sections and retaining the correct merged implementation for each
block. Preserve the existing restore-flag wiring through
SnapClient.SetCheckPrivilegeTableRowsCollateCompatiblity and
GetCheckPrivilegeTableRowsCollateCompatiblity, ensuring the file compiles.

Comment on lines +65 to +73
var createCallBacks []func(*SnapFileImporter) error
var closeCallBacks []func(*SnapFileImporter) error

createCallBacks = append(createCallBacks, func(importer *SnapFileImporter) error {
return setFn(importer, rc.rateLimit)
})
closeCallBacks = append(createCallBacks, func(importer *SnapFileImporter) error {
return setFn(importer, 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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

closeCallBacks is built from createCallBacks.

Line 71 appends the close callback to createCallBacks, not to closeCallBacks. The close list then also contains the create callback, so closing the importer sets the rate limit twice: first to rc.rateLimit, then to 0. The final value is correct, but the extra call makes the mock diverge from production behavior.

🐛 Proposed fix
-	closeCallBacks = append(createCallBacks, func(importer *SnapFileImporter) error {
+	closeCallBacks = append(closeCallBacks, func(importer *SnapFileImporter) error {
 		return setFn(importer, 0)
 	})
📝 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
var createCallBacks []func(*SnapFileImporter) error
var closeCallBacks []func(*SnapFileImporter) error
createCallBacks = append(createCallBacks, func(importer *SnapFileImporter) error {
return setFn(importer, rc.rateLimit)
})
closeCallBacks = append(createCallBacks, func(importer *SnapFileImporter) error {
return setFn(importer, 0)
})
var createCallBacks []func(*SnapFileImporter) error
var closeCallBacks []func(*SnapFileImporter) error
createCallBacks = append(createCallBacks, func(importer *SnapFileImporter) error {
return setFn(importer, rc.rateLimit)
})
closeCallBacks = append(closeCallBacks, func(importer *SnapFileImporter) error {
return setFn(importer, 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/restore/snap_client/export_test.go` around lines 65 - 73, Update the
callback registration in the test setup so the close callback is appended to
closeCallBacks rather than createCallBacks. Keep createCallBacks containing only
the rate-limit initialization callback, ensuring close execution invokes only
the callback that resets the rate limit.

Comment on lines +137 to +145
// skip check collate but type mismatch
mockedDBTI = dbTI.Clone()
mockedDBTI.Columns[1].SetCollate("utf8mb4_bin")
mockedUserTI.Columns[1].FieldType.SetFlen(2000) // Columns[1] is `DB` char(64)
_, err = snapclient.CheckSysTableCompatibility(cluster.Domain, []*metautil.Table{{
DB: tmpSysDB,
Info: mockedDBTI,
}}, true)
require.NoError(t, 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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

The type-mismatch case mutates the wrong table info.

The comment states "skip check collate but type mismatch". The code changes mockedUserTI.Columns[1], but it passes mockedDBTI to CheckSysTableCompatibility. The mutation has no effect on the assertion, so this case duplicates the previous case.

🧪 Proposed fix
 	mockedDBTI = dbTI.Clone()
 	mockedDBTI.Columns[1].SetCollate("utf8mb4_bin")
-	mockedUserTI.Columns[1].FieldType.SetFlen(2000) // Columns[1] is `DB` char(64)
+	mockedDBTI.Columns[1].FieldType.SetFlen(2000) // Columns[1] is `DB` char(64)
 	_, err = snapclient.CheckSysTableCompatibility(cluster.Domain, []*metautil.Table{{
 		DB:   tmpSysDB,
 		Info: mockedDBTI,
 	}}, true)
-	require.NoError(t, err)
+	require.True(t, berrors.ErrRestoreIncompatibleSys.Equal(err))

Confirm the expected result before you apply the assertion change.

📝 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
// skip check collate but type mismatch
mockedDBTI = dbTI.Clone()
mockedDBTI.Columns[1].SetCollate("utf8mb4_bin")
mockedUserTI.Columns[1].FieldType.SetFlen(2000) // Columns[1] is `DB` char(64)
_, err = snapclient.CheckSysTableCompatibility(cluster.Domain, []*metautil.Table{{
DB: tmpSysDB,
Info: mockedDBTI,
}}, true)
require.NoError(t, err)
// skip check collate but type mismatch
mockedDBTI = dbTI.Clone()
mockedDBTI.Columns[1].SetCollate("utf8mb4_bin")
mockedDBTI.Columns[1].FieldType.SetFlen(2000) // Columns[1] is `DB` char(64)
_, err = snapclient.CheckSysTableCompatibility(cluster.Domain, []*metautil.Table{{
DB: tmpSysDB,
Info: mockedDBTI,
}}, true)
require.True(t, berrors.ErrRestoreIncompatibleSys.Equal(err))
🤖 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/snap_client/systable_restore_test.go` around lines 137 - 145,
Update the type-mismatch setup in the test around CheckSysTableCompatibility to
mutate the same table info that is passed to it: change the relevant column on
mockedDBTI rather than mockedUserTI. Preserve the expected no-error assertion
for this case, confirming the collate difference remains skipped while the DB
column type mismatch is exercised.

Comment on lines +395 to +397
func TestMonitorTheSystemTableIncremental(t *testing.T) {
require.Equal(t, int64(253), session.CurrentBootstrapVersion)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Read the bootstrap version declared on this branch.
rg -n 'CurrentBootstrapVersion\s*=' pkg/session

Repository: pingcap/tidb

Length of output: 228


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- branch and status ---'
git branch --show-current
git status --short
printf '%s\n' '--- bootstrap declarations and references ---'
rg -n -C 4 'currentBootstrapVersion|CurrentBootstrapVersion' pkg/session br/pkg/restore/snap_client/systable_restore_test.go
printf '%s\n' '--- test context ---'
sed -n '360,415p' br/pkg/restore/snap_client/systable_restore_test.go
printf '%s\n' '--- nearby session testutil ---'
sed -n '1,70p' pkg/session/testutil.go

Repository: pingcap/tidb

Length of output: 50368


Update the bootstrap-version assertion.

release-8.1 defines session.CurrentBootstrapVersion as version199, so the assertion for 253 fails. Use the branch value.

🤖 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/snap_client/systable_restore_test.go` around lines 395 - 397,
Update TestMonitorTheSystemTableIncremental to assert
session.CurrentBootstrapVersion equals the release-8.1 branch value version199
instead of 253.

Comment on lines +807 to +811
if colCount != len(collateCompatibilityColumnMap.columns) {
return errors.Annotatef(berrors.ErrRestoreIncompatibleSys,
"incompatible column collate, downstream table %s.%s has only %d columns with collate utf8mb4_bin",
dbNameL, tableNameL, colCount)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Fix the collate name in the downstream error message.

This branch validates the downstream collate utf8mb4_general_ci, but the message reports utf8mb4_bin. The message misleads during diagnosis.

🔤 Proposed fix
 	if colCount != len(collateCompatibilityColumnMap.columns) {
 		return errors.Annotatef(berrors.ErrRestoreIncompatibleSys,
-			"incompatible column collate, downstream table %s.%s has only %d columns with collate utf8mb4_bin",
+			"incompatible column collate, downstream table %s.%s has only %d columns with collate utf8mb4_general_ci",
 			dbNameL, tableNameL, colCount)
 	}
📝 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
if colCount != len(collateCompatibilityColumnMap.columns) {
return errors.Annotatef(berrors.ErrRestoreIncompatibleSys,
"incompatible column collate, downstream table %s.%s has only %d columns with collate utf8mb4_bin",
dbNameL, tableNameL, colCount)
}
if colCount != len(collateCompatibilityColumnMap.columns) {
return errors.Annotatef(berrors.ErrRestoreIncompatibleSys,
"incompatible column collate, downstream table %s.%s has only %d columns with collate utf8mb4_general_ci",
dbNameL, tableNameL, colCount)
}
🤖 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/snap_client/systable_restore.go` around lines 807 - 811,
Update the error message in the colCount validation branch to report
utf8mb4_general_ci instead of utf8mb4_bin, keeping the existing error type,
formatting, and control flow unchanged.

Comment thread br/pkg/task/restore.go
Comment on lines +279 to +287
<<<<<<< HEAD
=======
flags.Bool(flagAllowPITRFromIncremental, true, "whether make incremental restore compatible with later log restore"+
" default is true, the incremental restore will not perform rewrite on the incremental data"+
" meanwhile the incremental restore will not allow to restore 3 backfilled type ddl jobs,"+
" these ddl jobs are Add index, Modify column and Reorganize partition")
flags.Bool(FlagSysCheckCollation, false, "whether check the privileges table rows to permit to restore the privilege data"+
" from utf8mb4_bin collate column to utf8mb4_general_ci collate column")
>>>>>>> 0cb39391dce (br: support restore privileges tables from v6.5 to v7.5 (#64668))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Unresolved merge conflict markers block compilation.

The file still contains <<<<<<< HEAD, =======, and >>>>>>> 0cb39391dce markers at lines 279-287, 408-418, 564-582, 828, and 883-887. Go cannot parse this file. Resolve every conflict before merge.

Two resolutions need attention:

  1. Lines 564-582: the HEAD side calls restore.CheckKeyspaceBREnable, client.LoadRestoreStores(ctx), and client.SetConcurrency(uint(cfg.Concurrency)). The incoming side calls only client.SetRewriteMode(ctx) and client.SetCheckPrivilegeTableRowsCollateCompatiblity(cfg.SysCheckCollation). If you keep only the incoming side, the restore stores never load and the concurrency stays unset. Keep LoadRestoreStores and SetConcurrency together with the two new calls, and confirm that SnapClient.SetRewriteMode(ctx) exists on this branch.
  2. Lines 883-893: the if err != nil body and the loadSysTablePhysical fallback sit outside the conflict block. After you resolve the markers, verify that canLoadSysTablePhysical and err are declared in the retained branch, and that the HEAD code the marker at line 828 hides is preserved or intentionally dropped.

Also applies to: 408-418, 564-582, 828-828, 883-893

🤖 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/restore.go` around lines 279 - 287, Resolve every merge conflict
marker in br/pkg/task/restore.go, including the blocks around flag registration,
restore client setup, and physical system-table loading. In the restore setup,
retain restore.CheckKeyspaceBREnable, client.LoadRestoreStores(ctx), and
client.SetConcurrency(uint(cfg.Concurrency)) together with SetRewriteMode(ctx)
and SetCheckPrivilegeTableRowsCollateCompatiblity(cfg.SysCheckCollation),
confirming SnapClient.SetRewriteMode exists. Ensure the retained branch declares
canLoadSysTablePhysical and err before the subsequent error handling and
fallback, and preserve or intentionally remove the code hidden near line 828.

Comment thread br/pkg/utils/misc_test.go
Comment on lines +81 to +83
typeEq, collateEq := IsTypeCompatible(*src, *target)
require.False(t, typeEq)
require.True(t, collateEq)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

This case does not exercise the length check.

The block comment states "src flen > target", but the target sets a flag value, not a length. The value 99 sets NotNullFlag, PriKeyFlag, UnsignedFlag, and ZerofillFlag. IsTypeCompatible then returns false at the not-null flag check, before it compares lengths. The assertion passes for the wrong reason.

Set the target length so the case reaches the length comparison.

🤖 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/misc_test.go` around lines 81 - 83, Update the test case around
IsTypeCompatible so the target column’s length is explicitly smaller than the
source length, rather than assigning 99 to its flag field. Preserve the existing
assertions and ensure the inputs reach the length-comparison branch instead of
returning early on flag incompatibility.

Comment thread br/pkg/utils/misc.go
Comment on lines +60 to +70
func IsTypeCompatible(src types.FieldType, target types.FieldType) (typeEq, collateEq bool) {
collateEq = src.GetCollate() == target.GetCollate()
if mysql.HasNotNullFlag(src.GetFlag()) != mysql.HasNotNullFlag(target.GetFlag()) {
return false
return false, collateEq
}
if mysql.HasUnsignedFlag(src.GetFlag()) != mysql.HasUnsignedFlag(target.GetFlag()) {
return false
return false, collateEq
}
srcEType, dstEType := src.EvalType(), target.EvalType()
if srcEType != dstEType {
return false
return false, collateEq

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Find all IsTypeCompatible call sites and check the assignment arity.
rg -nP --type=go -C3 '\bIsTypeCompatible\s*\('

Repository: pingcap/tidb

Length of output: 150


🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' 'Tracked Go files containing IsTypeCompatible:'
git grep -n -w -- 'IsTypeCompatible' -- '*.go' || true
printf '%s\n' 'Definition and client.go context:'
git grep -n -C 5 -- 'func IsTypeCompatible' -- 'br/pkg/utils/misc.go' || true
git grep -n -C 5 -- 'IsTypeCompatible' -- 'br/pkg/restore/client.go' || true
printf '%s\n' 'Relevant tracked files:'
git ls-files 'br/pkg/utils/misc.go' 'br/pkg/restore/client.go'

Repository: pingcap/tidb

Length of output: 3976


🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' 'Restore client call context:'
sed -n '1228,1270p' br/pkg/restore/client.go
printf '%s\n' 'Other caller context:'
sed -n '690,718p' br/pkg/restore/snap_client/systable_restore.go
printf '%s\n' 'Function return paths:'
sed -n '53,100p' br/pkg/utils/misc.go

Repository: pingcap/tidb

Length of output: 5556


Update the br/pkg/restore/client.go:1256 call for the two-value return. IsTypeCompatible returns (typeEq, collateEq), but this call uses it as one boolean and does not compile.

🤖 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/misc.go` around lines 60 - 70, Update the IsTypeCompatible call
in the restore client type-checking logic to receive both returned values, using
the typeEq result for the existing compatibility decision and handling collateEq
as required by the surrounding logic. Ensure the call no longer treats the
two-value return as a single boolean and compiles successfully.

This branch has not been deployed

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

Labels

do-not-merge/cherry-pick-not-approved 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.1 This PR is cherry-picked to release-8.1 from a source PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants