Skip to content

session: initialize masking policy table before upgrade DDL#69763

Open
expxiaoli wants to merge 7 commits into
pingcap:masterfrom
expxiaoli:fix_69464_v3
Open

session: initialize masking policy table before upgrade DDL#69763
expxiaoli wants to merge 7 commits into
pingcap:masterfrom
expxiaoli:fix_69464_v3

Conversation

@expxiaoli

@expxiaoli expxiaoli commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: close #69464

Problem Summary:

During rolling upgrade, a newly started TiDB may repeatedly crash in bootstrap upgrade. upgradeToVer190 can run reentrant MODIFY COLUMN DDLs before upgradeToVer260 creates mysql.tidb_masking_policy. The masking policy sync path used by ordinary DDL may query mysql.tidb_masking_policy, so the DDL job fails with Table 'mysql.tidb_masking_policy' doesn't exist, and bootstrap upgrade exits fatally.

What changed and how does it work?

This PR reverts the previous DDL-layer workaround that tolerated a missing masking policy system table during bootstrap or upgrade.

Instead, it initializes bootstrap-dependent system tables before running bootstrap or upgrade DDL. Specifically, mysql.tidb_masking_policy is created through Meta KV before runInBootstrapSession, so upgrade DDLs that consult masking policy metadata can run safely even when the stored bootstrap version is older than version260.

The existing upgradeToVer260 CREATE TABLE IF NOT EXISTS step is kept as an idempotent versioned upgrade step.

This PR also extends the existing masking policy bootstrap upgrade test to cover upgrading from bootstrap version 189, which reproduces the failing upgradeToVer190 path. The existing 254 coverage is kept.

Check List

Tests

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

Executed:

  • GOPATH=/Users/xiaoli/go GOSUMDB=sum.golang.org ./tools/check/failpoint-go-test.sh pkg/session/test/bootstraptest -run TestUpgradeVersion260MaskingPolicy -count=1
  • GOPATH=/Users/xiaoli/go GOSUMDB=sum.golang.org 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.

Fix an issue that TiDB might repeatedly crash during rolling upgrade when bootstrap upgrade DDL runs before mysql.tidb_masking_policy is created.

Summary by CodeRabbit

  • Bug Fixes
    • Standardized masking-policy DDL/cleanup behavior when mysql.tidb_masking_policy is missing, consistently returning “table not exists” without special bootstrap/upgrade suppression.
    • Ensured classic-kernel upgrade bootstraps masking-policy “next-gen” dependent system tables when version conditions match.
    • Prevented masking-policy physical table ID reuse after upgrade/restart.
  • Tests
    • Replaced missing-sys-table failpoint coverage with tests asserting masking-policy operations require the sys-table.
    • Strengthened masking-policy upgrade validation with restart and rename scenarios.
  • Documentation
    • Updated DDL/session test case mapping references for masking-policy coverage.

@ti-chi-bot ti-chi-bot Bot added release-note Denotes a PR that will be considered when it comes time to generate release notes. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Jul 10, 2026
@coderabbitai

coderabbitai Bot commented Jul 10, 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

Bootstrap now creates missing masking-policy system tables during eligible upgrades, while masking-policy DDL paths remove bootstrap-specific suppression of missing-table errors. Upgrade and restart tests verify ID allocation, table recreation, and rename behavior.

Changes

Masking policy bootstrap

Layer / File(s) Summary
Bootstrap dependent table creation
pkg/session/session.go, pkg/session/test/bootstraptest/bootstrap_upgrade_test.go, .agents/skills/tidb-test-guidelines/references/session-case-map.md
Bootstrap detects and creates missing masking-policy tables, propagates initialization errors, and upgrade tests validate non-reserved IDs, recreation, and restart behavior.
Masking-policy missing-table handling
pkg/ddl/masking_policy.go, pkg/ddl/masking_policy_internal_test.go, pkg/ddl/table.go, .agents/skills/tidb-test-guidelines/references/ddl-case-map.md
Masking-policy operations use direct missing-table checks or propagate errors; rename callers pass context, and tests require missing-table errors.
DDL context start-mode cleanup
pkg/ddl/ddl.go
The internal DDL context no longer stores or receives the executor start mode.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Possibly related PRs

  • pingcap/tidb#69531: Modifies missing masking-policy system-table behavior and related tests.

Sequence Diagram(s)

sequenceDiagram
  participant bootstrapSessionImpl
  participant initBootstrapDependentTables
  participant createAndSplitTablesIfNotExists
  participant BootstrapUpgradeTests
  bootstrapSessionImpl->>initBootstrapDependentTables: initialize dependent tables
  initBootstrapDependentTables->>createAndSplitTablesIfNotExists: create missing masking-policy tables
  createAndSplitTablesIfNotExists-->>bootstrapSessionImpl: return initialization status
  BootstrapUpgradeTests->>BootstrapUpgradeTests: verify IDs, recreation, and restart behavior
Loading

Suggested labels: approved, lgtm, ok-to-test

Suggested reviewers: d3hunter, terry1purcell, leavrth, gmhdbjd

Poem

I’m a rabbit hopping through schemas bright,
Missing tables bloom in bootstrap light.
Safe IDs bound, old names depart,
Restart checks guard the system’s heart. 🐇

🚥 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 is concise and clearly summarizes the main change: initializing the masking policy table before upgrade DDL.
Description check ✅ Passed The description includes the issue number, problem summary, implementation details, tests, and release note.
Linked Issues check ✅ Passed The changes address #69464 by creating the masking policy table before bootstrap upgrade DDL and extending coverage for the failing path.
Out of Scope Changes check ✅ Passed The diff is focused on the upgrade crash fix; the remaining edits are test coverage, minor formatting, and supporting references.
✨ 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.

Comment thread pkg/session/session.go Outdated
if err != nil {
return nil, err
}
err = initBootstrapDependentTables(store)

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.

maybe put into InitDDLTables, and consider the difference between classic and nextgen

@codecov

codecov Bot commented Jul 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 8.82353% with 62 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.5806%. Comparing base (10292a4) to head (6c2d407).
⚠️ Report is 4 commits behind head on master.

Additional details and impacted files
@@               Coverage Diff                @@
##             master     #69763        +/-   ##
================================================
- Coverage   76.3188%   75.5806%   -0.7383%     
================================================
  Files          2041       2084        +43     
  Lines        560066     582304     +22238     
================================================
+ Hits         427436     440109     +12673     
- Misses       131729     140082      +8353     
- Partials        901       2113      +1212     
Flag Coverage Δ
integration 45.5309% <8.8235%> (+5.8256%) ⬆️

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

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

@expxiaoli

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@expxiaoli

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@expxiaoli

Copy link
Copy Markdown
Contributor Author

/retest-required

@goransh-buh

Copy link
Copy Markdown

Looks good to me. The change is minimal and targeted, which I appreciate. LGTM once CI is green.

@expxiaoli

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@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.

🧹 Nitpick comments (1)
pkg/ddl/masking_policy_internal_test.go (1)

26-56: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider adding test cases for updateMaskingPolicyTableIDAfterTruncate and updateMaskingPolicyNamesAfterRename.

Both functions had error handling changes and use the same failpoint path, but are not covered. updateMaskingPolicyNamesAfterRename is especially worth testing since its signature changed to ctx context.Context. Adding entries to the existing test table is low-effort:

♻️ Suggested additional test cases
 	tests := []struct {
 		name string
 		run  func() error
 	}{
 		{
 			name: "table",
 			run: func() error {
 				return w.dropMaskingPoliciesOnTable(jobCtx, 1)
 			},
 		},
 		{
 			name: "column",
 			run: func() error {
 				return w.dropMaskingPoliciesOnColumn(jobCtx, 1, 1)
 			},
 		},
+		{
+			name: "truncate",
+			run: func() error {
+				return w.updateMaskingPolicyTableIDAfterTruncate(jobCtx, 1, 2)
+			},
+		},
+		{
+			name: "rename",
+			run: func() error {
+				return w.updateMaskingPolicyNamesAfterRename(context.Background(), 1,
+					ast.CIStr{}, ast.CIStr{}, ast.CIStr{}, ast.CIStr{})
+			},
+		},
 	}
🤖 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 `@pkg/ddl/masking_policy_internal_test.go` around lines 26 - 56, Extend
TestDropMaskingPoliciesRequiresSysTable with table entries invoking
updateMaskingPolicyTableIDAfterTruncate and updateMaskingPolicyNamesAfterRename,
passing the existing job context as required by the updated context-aware
signature. Assert both return an error matching infoschema.ErrTableNotExists,
consistent with the existing table and column cases.
🤖 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.

Nitpick comments:
In `@pkg/ddl/masking_policy_internal_test.go`:
- Around line 26-56: Extend TestDropMaskingPoliciesRequiresSysTable with table
entries invoking updateMaskingPolicyTableIDAfterTruncate and
updateMaskingPolicyNamesAfterRename, passing the existing job context as
required by the updated context-aware signature. Assert both return an error
matching infoschema.ErrTableNotExists, consistent with the existing table and
column cases.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 879dda0f-73ea-4012-86df-33f1dc15bac8

📥 Commits

Reviewing files that changed from the base of the PR and between 972444e and ae108e9.

📒 Files selected for processing (6)
  • .agents/skills/tidb-test-guidelines/references/ddl-case-map.md
  • .agents/skills/tidb-test-guidelines/references/session-case-map.md
  • pkg/ddl/masking_policy.go
  • pkg/ddl/masking_policy_internal_test.go
  • pkg/session/session.go
  • pkg/session/test/bootstraptest/bootstrap_upgrade_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/session/session.go

@expxiaoli

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@expxiaoli

Copy link
Copy Markdown
Contributor Author

/retest-required

@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.

🧹 Nitpick comments (1)
pkg/ddl/masking_policy_internal_test.go (1)

32-65: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Restore missing-table coverage for modified-column synchronization.

syncMaskingPolicyForModifiedColumn now propagates the lookup error (pkg/ddl/masking_policy.go, Lines 657-660), but this table no longer exercises that changed path. Add a non-nil table/old-column/new-column case asserting infoschema.ErrTableNotExists; the replaced test covered it.

🤖 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 `@pkg/ddl/masking_policy_internal_test.go` around lines 32 - 65, Restore a test
case in the masking-policy test table that invokes
syncMaskingPolicyForModifiedColumn with non-nil table, old-column, and
new-column inputs. Assert that the call returns infoschema.ErrTableNotExists,
preserving coverage for the propagated missing-table lookup error alongside the
existing table, column, truncate, and rename cases.
🤖 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.

Nitpick comments:
In `@pkg/ddl/masking_policy_internal_test.go`:
- Around line 32-65: Restore a test case in the masking-policy test table that
invokes syncMaskingPolicyForModifiedColumn with non-nil table, old-column, and
new-column inputs. Assert that the call returns infoschema.ErrTableNotExists,
preserving coverage for the propagated missing-table lookup error alongside the
existing table, column, truncate, and rename cases.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: d3ac040e-d170-41d4-8c12-288f4d1295a0

📥 Commits

Reviewing files that changed from the base of the PR and between 4894ac0 and e96c17b.

📒 Files selected for processing (8)
  • .agents/skills/tidb-test-guidelines/references/ddl-case-map.md
  • .agents/skills/tidb-test-guidelines/references/session-case-map.md
  • pkg/ddl/ddl.go
  • pkg/ddl/masking_policy.go
  • pkg/ddl/masking_policy_internal_test.go
  • pkg/ddl/table.go
  • pkg/session/session.go
  • pkg/session/test/bootstraptest/bootstrap_upgrade_test.go
💤 Files with no reviewable changes (1)
  • pkg/ddl/ddl.go

@expxiaoli

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@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.

🧹 Nitpick comments (2)
pkg/ddl/masking_policy.go (1)

537-548: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider documenting the new "table must already exist" invariant.

These functions used to swallow ErrTableNotExists during bootstrap/upgrade; now they always propagate it, relying on initBootstrapDependentTables (pkg/session/session.go) to have created mysql.tidb_masking_policy before any upgrade DDL runs. That cross-file contract isn't obvious from this file alone — a short comment (similar to the one added on dropMaskingPoliciesByDBName) would help future maintainers avoid reintroducing the original bug (issue #69464) if this invariant is ever broken.

As per coding guidelines: "Comments SHOULD explain non-obvious intent, constraints, invariants, concurrency guarantees, SQL/compatibility contracts, or important performance trade-offs."

📝 Example comment to add near dropMaskingPoliciesOnTable
+// dropMaskingPoliciesOnTable assumes mysql.tidb_masking_policy already exists;
+// bootstrap guarantees this via initBootstrapDependentTables before any
+// upgrade DDL that may reach this code path runs (see issue `#69464`).
 func (w *worker) dropMaskingPoliciesOnTable(jobCtx *jobContext, tableID int64) error {

Also applies to: 589-600, 569-587, 604-629, 647-692

🤖 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 `@pkg/ddl/masking_policy.go` around lines 537 - 548, Add a concise comment near
dropMaskingPoliciesOnTable and the related masking-policy cleanup functions
explaining that mysql.tidb_masking_policy must already exist because
initBootstrapDependentTables creates it before upgrade DDL, so ErrTableNotExists
must be propagated rather than swallowed. Keep the comment focused on this
cross-file invariant and apply it consistently to all listed cleanup helpers.

Source: Coding guidelines

pkg/ddl/masking_policy_internal_test.go (1)

28-86: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

No test coverage for dropMaskingPoliciesByDBName's missing-table behavior.

This is the only masking-policy DDL helper that still swallows ErrTableNotExists (best-effort for DROP DATABASE). Since it calls w.sess.Execute directly instead of going through queryMaskingPoliciesFromSysTable, it can't be dropped into this failpoint-based table (a bare &worker{} would nil-panic on w.sess). Given it's the one function with the opposite contract from everything else touched in this PR, it seems worth a dedicated regression test (e.g., via the existing session/testkit-based masking policy test setup) asserting it returns nil when the sys table is missing.

🤖 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 `@pkg/ddl/masking_policy_internal_test.go` around lines 28 - 86, Add dedicated
regression coverage for dropMaskingPoliciesByDBName using the existing
session/testkit masking-policy setup, because the current bare worker test
cannot exercise its direct w.sess.Execute path. Simulate a missing
masking-policy system table and assert dropMaskingPoliciesByDBName returns nil,
preserving its best-effort DROP DATABASE contract rather than expecting
ErrTableNotExists.
🤖 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.

Nitpick comments:
In `@pkg/ddl/masking_policy_internal_test.go`:
- Around line 28-86: Add dedicated regression coverage for
dropMaskingPoliciesByDBName using the existing session/testkit masking-policy
setup, because the current bare worker test cannot exercise its direct
w.sess.Execute path. Simulate a missing masking-policy system table and assert
dropMaskingPoliciesByDBName returns nil, preserving its best-effort DROP
DATABASE contract rather than expecting ErrTableNotExists.

In `@pkg/ddl/masking_policy.go`:
- Around line 537-548: Add a concise comment near dropMaskingPoliciesOnTable and
the related masking-policy cleanup functions explaining that
mysql.tidb_masking_policy must already exist because
initBootstrapDependentTables creates it before upgrade DDL, so ErrTableNotExists
must be propagated rather than swallowed. Keep the comment focused on this
cross-file invariant and apply it consistently to all listed cleanup helpers.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 1234abcf-1e50-441a-a764-7018424ea93d

📥 Commits

Reviewing files that changed from the base of the PR and between 4894ac0 and 9d360b8.

📒 Files selected for processing (8)
  • .agents/skills/tidb-test-guidelines/references/ddl-case-map.md
  • .agents/skills/tidb-test-guidelines/references/session-case-map.md
  • pkg/ddl/ddl.go
  • pkg/ddl/masking_policy.go
  • pkg/ddl/masking_policy_internal_test.go
  • pkg/ddl/table.go
  • pkg/session/session.go
  • pkg/session/test/bootstraptest/bootstrap_upgrade_test.go
💤 Files with no reviewable changes (1)
  • pkg/ddl/ddl.go

@expxiaoli

Copy link
Copy Markdown
Contributor Author

🧹 Nitpick comments (2)

pkg/ddl/masking_policy.go (1)> 537-548: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider documenting the new "table must already exist" invariant.
These functions used to swallow ErrTableNotExists during bootstrap/upgrade; now they always propagate it, relying on initBootstrapDependentTables (pkg/session/session.go) to have created mysql.tidb_masking_policy before any upgrade DDL runs. That cross-file contract isn't obvious from this file alone — a short comment (similar to the one added on dropMaskingPoliciesByDBName) would help future maintainers avoid reintroducing the original bug (issue #69464) if this invariant is ever broken.
As per coding guidelines: "Comments SHOULD explain non-obvious intent, constraints, invariants, concurrency guarantees, SQL/compatibility contracts, or important performance trade-offs."

📝 Example comment to add near dropMaskingPoliciesOnTable

+// dropMaskingPoliciesOnTable assumes mysql.tidb_masking_policy already exists;
+// bootstrap guarantees this via initBootstrapDependentTables before any
+// upgrade DDL that may reach this code path runs (see issue `#69464`).
 func (w *worker) dropMaskingPoliciesOnTable(jobCtx *jobContext, tableID int64) error {

Also applies to: 589-600, 569-587, 604-629, 647-692

🤖 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 `@pkg/ddl/masking_policy.go` around lines 537 - 548, Add a concise comment near
dropMaskingPoliciesOnTable and the related masking-policy cleanup functions
explaining that mysql.tidb_masking_policy must already exist because
initBootstrapDependentTables creates it before upgrade DDL, so ErrTableNotExists
must be propagated rather than swallowed. Keep the comment focused on this
cross-file invariant and apply it consistently to all listed cleanup helpers.

Source: Coding guidelines

pkg/ddl/masking_policy_internal_test.go (1)> 28-86: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

No test coverage for dropMaskingPoliciesByDBName's missing-table behavior.
This is the only masking-policy DDL helper that still swallows ErrTableNotExists (best-effort for DROP DATABASE). Since it calls w.sess.Execute directly instead of going through queryMaskingPoliciesFromSysTable, it can't be dropped into this failpoint-based table (a bare &worker{} would nil-panic on w.sess). Given it's the one function with the opposite contract from everything else touched in this PR, it seems worth a dedicated regression test (e.g., via the existing session/testkit-based masking policy test setup) asserting it returns nil when the sys table is missing.

🤖 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 `@pkg/ddl/masking_policy_internal_test.go` around lines 28 - 86, Add dedicated
regression coverage for dropMaskingPoliciesByDBName using the existing
session/testkit masking-policy setup, because the current bare worker test
cannot exercise its direct w.sess.Execute path. Simulate a missing
masking-policy system table and assert dropMaskingPoliciesByDBName returns nil,
preserving its best-effort DROP DATABASE contract rather than expecting
ErrTableNotExists.

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

Nitpick comments:
In `@pkg/ddl/masking_policy_internal_test.go`:
- Around line 28-86: Add dedicated regression coverage for
dropMaskingPoliciesByDBName using the existing session/testkit masking-policy
setup, because the current bare worker test cannot exercise its direct
w.sess.Execute path. Simulate a missing masking-policy system table and assert
dropMaskingPoliciesByDBName returns nil, preserving its best-effort DROP
DATABASE contract rather than expecting ErrTableNotExists.

In `@pkg/ddl/masking_policy.go`:
- Around line 537-548: Add a concise comment near dropMaskingPoliciesOnTable and
the related masking-policy cleanup functions explaining that
mysql.tidb_masking_policy must already exist because
initBootstrapDependentTables creates it before upgrade DDL, so ErrTableNotExists
must be propagated rather than swallowed. Keep the comment focused on this
cross-file invariant and apply it consistently to all listed cleanup helpers.

ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 1234abcf-1e50-441a-a764-7018424ea93d

📥 Commits
Reviewing files that changed from the base of the PR and between 4894ac0 and 9d360b8.

📒 Files selected for processing (8)

  • .agents/skills/tidb-test-guidelines/references/ddl-case-map.md
  • .agents/skills/tidb-test-guidelines/references/session-case-map.md
  • pkg/ddl/ddl.go
  • pkg/ddl/masking_policy.go
  • pkg/ddl/masking_policy_internal_test.go
  • pkg/ddl/table.go
  • pkg/session/session.go
  • pkg/session/test/bootstraptest/bootstrap_upgrade_test.go

💤 Files with no reviewable changes (1)

Thanks for the suggestions. We prefer not to change the code in this PR.
The table requirement is already documented in initBootstrapDependentTables and covered by TestMaskingPolicyOperationsRequireSysTable, so adding the same comment to each helper would be repetitive. The dropMaskingPoliciesByDBName behavior existed before this PR, and onDropSchema already treats cleanup errors as best-effort.

@expxiaoli

Copy link
Copy Markdown
Contributor Author

/retest-required

Comment thread pkg/session/session.go
// bootstrap quickly, after bootstrapped, we will reset the lease time.
// TODO: Using a bootstrap tool for doing this may be better later.
func runInBootstrapSession(store kv.Storage, ver int64) {
func runInBootstrapSession(store kv.Storage, ver int64) error {

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.

currently, this method use log.Fatal to exit directly on non-retryable error, not return it

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 prefer to keep this design.
At this point we already hold the upgrade lock, and returning lets defer releaseFn() unlock and close the etcd session. log.Fatal would skip defers in production and leave the 10-second lease to expire.
Additionally, BootstrapSession already has an error-return contract and its caller handles startup failures, so propagating the error is safer and more testable.

Comment thread pkg/session/session.go Outdated
// TODO remove this after we can refactor below code out in this case.
logutil.BgLogger().Info("[upgrade] already upgraded by other nodes, switch to normal mode")
startMode = ddl.Normal
} else if err := initBootstrapDependentTables(store, currVer); err != nil {

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.

please add some explain comment on why it have to be run under the upgrade lock

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.

Agree, I will add comment later.

Comment thread pkg/session/session.go
dbID int64,
tables []TableBasicInfo,
) error {
existingTables, err := t.ListTables(ctx, dbID)

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.

please comment on why we have to check the table existance first, while InitDDLTables don't need

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.

Agree, I will add comment later.

Comment thread pkg/session/session.go
// initBootstrapDependentTables creates system tables that classic kernel upgrade
// DDL may consult before the ordinary upgrade DDL reaches their creation step.
func initBootstrapDependentTables(store kv.Storage, ver int64) error {
if !kerneltype.IsClassic() || ver <= notBootstrapped || ver >= version260 || currentBootstrapVersion < version260 {

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.

please comment, why those case we can skip

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.

Agree, I will add comment later.

@ti-chi-bot

ti-chi-bot Bot commented Jul 15, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: D3Hunter

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 approved needs-1-more-lgtm Indicates a PR needs 1 more LGTM. labels Jul 15, 2026
@ti-chi-bot

ti-chi-bot Bot commented Jul 15, 2026

Copy link
Copy Markdown

[LGTM Timeline notifier]

Timeline:

  • 2026-07-15 05:57:27.394584061 +0000 UTC m=+779633.430679147: ☑️ agreed by D3Hunter.

@ti-chi-bot ti-chi-bot Bot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Jul 15, 2026
@ti-chi-bot

ti-chi-bot Bot commented Jul 15, 2026

Copy link
Copy Markdown

@expxiaoli: 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
pull-error-log-review 6c2d407 link false /test pull-error-log-review

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.

@expxiaoli

Copy link
Copy Markdown
Contributor Author

/retest-required

2 similar comments
@expxiaoli

Copy link
Copy Markdown
Contributor Author

/retest-required

@expxiaoli

Copy link
Copy Markdown
Contributor Author

/retest-required

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

Labels

approved needs-1-more-lgtm Indicates a PR needs 1 more LGTM. release-note Denotes a PR that will be considered when it comes time to generate release notes. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TiDB upgrade to master repeatedly crashes in upgradeToVer190 doReentrantDDL on tidb_masking_policy

3 participants