Skip to content

statistics: stabilize TestNonLiteInitStatsWithTableIDs case (#67971)#70017

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

statistics: stabilize TestNonLiteInitStatsWithTableIDs case (#67971)#70017
ti-chi-bot wants to merge 1 commit into
pingcap:release-8.5from
ti-chi-bot:cherry-pick-67971-to-release-8.5

Conversation

@ti-chi-bot

@ti-chi-bot ti-chi-bot commented Jul 24, 2026

Copy link
Copy Markdown
Member

This is an automated cherry-pick of #67971

What problem does this PR solve?

Issue Number: ref #67176

Problem Summary:

The LFU stats cache is backed by Ristretto. New/non-resident entries are admitted asynchronously, but init stats builds a fresh stats cache in phases/chunks and later phases may read entries written by earlier phases/chunks. Without draining the async path at the required boundaries, init stats can observe missing or stale table snapshots.

What changed and how does it work?

  • Added WaitForAsyncUpdates to the stats-cache interfaces and implementations.
    • LFU delegates to Ristretto Wait().
    • Map cache implements it as a no-op.
  • Used the wait in init stats only where later reads or publishing depend on newly written entries:
    • after stats meta loading, before histogram loading reads the newly added tables;
    • after each histogram/TopN/bucket chunk, because one table's rows can span chunks;
    • after CalcPreScalar writes tables back, before replacing/publishing the cache;
    • after targeted refresh publishes refreshed tables to the global stats cache.

Check List

Tests

  • Unit test
  • Integration test
  • Manual test (Benchmark Test)
  • 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

  • Bug Fixes

    • Improved statistics cache initialization to ensure newly loaded data is immediately available for subsequent reads.
    • Prevented stale cache reads and inconsistent results while loading statistics in chunks.
    • Improved handling of partially initialized caches and cache capacity limits.
    • Reduced the risk of temporary resource leaks during cache initialization.
  • Tests

    • Strengthened cache synchronization checks for inserts, removals, evictions, and capacity changes.

Signed-off-by: ti-chi-bot <ti-community-prow-bot@tidb.io>
@ti-chi-bot ti-chi-bot added component/statistics do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. release-note-none Denotes a PR that doesn't merit a release note. sig/planner SIG: Planner size/L Denotes a PR that changes 100-499 lines, ignoring generated files. type/cherry-pick-for-release-8.5 This PR is cherry-picked to release-8.5 from a source PR. labels Jul 24, 2026
@ti-chi-bot

Copy link
Copy Markdown
Member Author

@0xPoe 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 added the cherry-pick-approved Cherry pick PR approved by release team. label Jul 24, 2026
@ti-chi-bot

ti-chi-bot Bot commented Jul 24, 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.

@ti-chi-bot

ti-chi-bot Bot commented Jul 24, 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 time-and-fate 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

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Statistics cache interfaces now expose asynchronous-update synchronization. LFU operations and tests use it for deterministic visibility, while statistics bootstrap drains updates between loading phases and conditionally publishes temporary cache contents.

Changes

Stats cache synchronization contract

Layer / File(s) Summary
Cache synchronization contract
pkg/statistics/handle/types/interfaces.go, pkg/statistics/handle/cache/...
WaitForAsyncUpdates() is added across cache interfaces and implementations, including the no-op map cache and test mock, and delegates to the active underlying cache.

LFU visibility semantics and tests

Layer / File(s) Summary
LFU visibility semantics and validation
pkg/statistics/handle/cache/internal/lfu/lfu_cache.go, pkg/statistics/handle/cache/internal/lfu/lfu_cache_test.go
LFU documentation describes buffered admissions and visibility ordering; tests wait for asynchronous updates before asserting reads, costs, lengths, and eviction outcomes.

Statistics bootstrap synchronization

Layer / File(s) Summary
Chunk loading and cache publication
pkg/statistics/handle/bootstrap.go
Statistics loading waits between chunks and phases, passes the computed full-cache state to histogram initialization, and publishes tables individually or replaces the global cache based on tableIDs, closing temporary caches afterward.

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

Sequence Diagram(s)

sequenceDiagram
  participant InitStats
  participant TemporaryStatsCache
  participant LFU
  participant GlobalStatsCache
  InitStats->>TemporaryStatsCache: Load metadata and statistic chunks
  TemporaryStatsCache->>LFU: Put chunk entries
  InitStats->>LFU: WaitForAsyncUpdates between phases
  InitStats->>GlobalStatsCache: Publish each table
  GlobalStatsCache->>LFU: WaitForAsyncUpdates
  InitStats->>TemporaryStatsCache: Close temporary cache
Loading

Possibly related PRs

  • pingcap/tidb#69883: Both changes rely on stats-cache asynchronous visibility ordering for statistics refresh correctness.

Suggested labels: type/bug, approved, lgtm, ok-to-test

Suggested reviewers: terry1purcell, yangkeao, wjhuang2016

Poem

I’m a rabbit with cache in my hat,
Waiting for writes—imagine that!
Chunks hop in line,
Fresh reads now shine,
And temp caches vanish—splat!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately reflects the main goal: stabilizing the TestNonLiteInitStatsWithTableIDs case.
Description check ✅ Passed The description follows the required template with problem summary, issue link, change details, checklist, and release note.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

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

🔧 golangci-lint (2.12.2)

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


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

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

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

Inline comments:
In `@pkg/statistics/handle/bootstrap.go`:
- Around line 362-369: Remove all cherry-pick conflict markers and reconcile the
bootstrap flow with the selected release branch. In
pkg/statistics/handle/bootstrap.go:362-369, use the release-compatible
initStatsHistograms4Chunk call while retaining per-chunk WaitForAsyncUpdates
synchronization; at 498-505, adapt the TopN invocation to the branch’s actual
helper signature; at 814-832 and 904-926, update targeted-cache and final-cache
publication plus cleanup to the release branch APIs and behavior.
- Around line 907-909: Update the direct bucket-loading loop in the bootstrap
flow to call cache.WaitForAsyncUpdates() after each chunk is processed, before
the next initStatsBuckets4Chunk invocation can read the cache. Match the
per-chunk wait placement used by initStatsBucketsByPaging, while retaining the
existing final drain and completion log.
🪄 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 Plus

Run ID: 34b4145c-b517-44d3-8dcc-7fb07b6101e6

📥 Commits

Reviewing files that changed from the base of the PR and between 10431d8 and 7e8bc06.

📒 Files selected for processing (9)
  • pkg/statistics/handle/bootstrap.go
  • pkg/statistics/handle/cache/internal/inner.go
  • pkg/statistics/handle/cache/internal/lfu/lfu_cache.go
  • pkg/statistics/handle/cache/internal/lfu/lfu_cache_test.go
  • pkg/statistics/handle/cache/internal/mapcache/map_cache.go
  • pkg/statistics/handle/cache/statscache.go
  • pkg/statistics/handle/cache/statscache_test.go
  • pkg/statistics/handle/cache/statscacheinner.go
  • pkg/statistics/handle/types/interfaces.go

Comment on lines +362 to +369
<<<<<<< HEAD
h.initStatsHistograms4Chunk(is, cache, iter, false)
=======
h.initStatsHistograms4Chunk(is, cache, iter, isFullCache(cache, totalMemory))
// The same table may continue in the next chunk. Drain LFU async admission/rejection
// before the next chunk reads or mutates it again.
cache.WaitForAsyncUpdates()
>>>>>>> 933e59fbe58 (statistics: stabilize TestNonLiteInitStatsWithTableIDs case (#67971))

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

Resolve the remaining cherry-pick conflicts before merge.

The <<<<<<<, =======, and >>>>>>> markers make this package uncompilable; the incoming alternatives also reference signatures and variables not present in the selected release branch.

  • pkg/statistics/handle/bootstrap.go#L362-L369: reconcile histogram initialization and retain the intended per-chunk synchronization.
  • pkg/statistics/handle/bootstrap.go#L498-L505: reconcile the TopN call with the release branch’s actual helper signature.
  • pkg/statistics/handle/bootstrap.go#L814-L832: reconcile targeted-cache publication with the release branch API.
  • pkg/statistics/handle/bootstrap.go#L904-L926: reconcile final cache publication and cleanup behavior.
📍 Affects 1 file
  • pkg/statistics/handle/bootstrap.go#L362-L369 (this comment)
  • pkg/statistics/handle/bootstrap.go#L498-L505
  • pkg/statistics/handle/bootstrap.go#L814-L832
  • pkg/statistics/handle/bootstrap.go#L904-L926
🤖 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/statistics/handle/bootstrap.go` around lines 362 - 369, Remove all
cherry-pick conflict markers and reconcile the bootstrap flow with the selected
release branch. In pkg/statistics/handle/bootstrap.go:362-369, use the
release-compatible initStatsHistograms4Chunk call while retaining per-chunk
WaitForAsyncUpdates synchronization; at 498-505, adapt the TopN invocation to
the branch’s actual helper signature; at 814-832 and 904-926, update
targeted-cache and final-cache publication plus cleanup to the release branch
APIs and behavior.

Comment on lines +907 to +909
// CalcPreScalar writes tables back; drain before replacing/publishing the cache.
cache.WaitForAsyncUpdates()
statslogutil.StatsLogger().Info("Complete loading the bucket", zap.Duration("duration", time.Since(start)))

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

Drain the direct bucket-loading loop between chunks.

This final drain occurs after all chunks, so it cannot prevent a following initStatsBuckets4Chunk call from reading a stale snapshot written by the preceding chunk. Add the same per-chunk wait used by initStatsBucketsByPaging after line 703.

Proposed fix
 		h.initStatsBuckets4Chunk(cache, iter)
+		cache.WaitForAsyncUpdates()
 	}
🤖 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/statistics/handle/bootstrap.go` around lines 907 - 909, Update the direct
bucket-loading loop in the bootstrap flow to call cache.WaitForAsyncUpdates()
after each chunk is processed, before the next initStatsBuckets4Chunk invocation
can read the cache. Match the per-chunk wait placement used by
initStatsBucketsByPaging, while retaining the existing final drain and
completion log.

@ti-chi-bot

ti-chi-bot Bot commented Jul 24, 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/check_dev 7e8bc06 link true /test check-dev
idc-jenkins-ci-tidb/unit-test 7e8bc06 link true /test unit-test
idc-jenkins-ci-tidb/check_dev_2 7e8bc06 link true /test check-dev2
idc-jenkins-ci-tidb/mysql-test 7e8bc06 link true /test mysql-test
idc-jenkins-ci-tidb/build 7e8bc06 link true /test build

Full PR test history. Your PR dashboard.

Details

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

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

Labels

cherry-pick-approved Cherry pick PR approved by release team. component/statistics do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. release-note-none Denotes a PR that doesn't merit a release note. sig/planner SIG: Planner size/L Denotes a PR that changes 100-499 lines, ignoring generated files. type/cherry-pick-for-release-8.5 This PR is cherry-picked to release-8.5 from a source PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants