Skip to content

statistics: remove historical stats feature#69889

Open
0xPoe wants to merge 5 commits into
pingcap:masterfrom
0xPoe:poe/remove-historical-stats-master
Open

statistics: remove historical stats feature#69889
0xPoe wants to merge 5 commits into
pingcap:masterfrom
0xPoe:poe/remove-historical-stats-master

Conversation

@0xPoe

@0xPoe 0xPoe commented Jul 16, 2026

Copy link
Copy Markdown
Member

What problem does this PR solve?

Issue Number: close #52826

Problem Summary: Recording historical statistics keeps large internal INSERT statements alive in the domain session pool and can use excessive memory. The feature is off by default, rarely used, and not worth its memory and maintenance cost, so this PR removes it.

What changed and how does it work?

  • Remove the historical stats feature: the RecordHistoricalStatsMeta/RecordHistoricalStatsToStorage write paths, the domain worker, the /stats/dump/{db}/{table}/{snapshot} HTTP API, related metrics/dashboard panels, plumbing, and tests.
  • Keep SQL compatibility: PLAN REPLAYER DUMP ... WITH STATS AS OF TIMESTAMP ... is still accepted — the clause is ignored, the dump contains current statistics, and a warning is reported. tidb_enable_historical_stats and tidb_enable_historical_stats_for_capture stay registered as no-op variables that report a warning when set to ON; mysql.stats_history/mysql.stats_meta_history are kept so upgraded clusters keep working.
  • Drain legacy data: stats GC still clears leftover rows in the two history tables after tidb_historical_stats_duration. This also fixes a bug in ClearOutdatedHistoryStats that deleted at most one 50-row batch of mysql.stats_history per GC round (and derived the batch count from the wrong table), which would have left legacy rows behind forever; regression tests cover both drain paths.
  • Log a warning when serving pre-upgrade capture_replayer_*.zip bundles, since they contain no statistics and no longer get download-time stats injection.

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.

The historical statistics feature has been removed. `tidb_enable_historical_stats` and `tidb_enable_historical_stats_for_capture` become no-op variables that report a warning when enabled, and the `/stats/dump/{db}/{table}/{snapshot}` HTTP API is removed. The `PLAN REPLAYER DUMP ... WITH STATS AS OF TIMESTAMP` syntax is still accepted for compatibility, but the clause is ignored, a warning is reported, and the dump contains current statistics. Leftover data in `mysql.stats_history` and `mysql.stats_meta_history` is cleared by stats GC after the retention window set by `tidb_historical_stats_duration`.

Summary by CodeRabbit

  • New Features
    • Plan Replayer dumps current (latest) statistics; WITH STATS AS OF TIMESTAMP is accepted but ignored, and a warning is shown.
    • Stats download APIs now serve current table statistics only (no snapshot selection).
  • Bug Fixes
    • Improved cleanup of legacy historical statistics after table drops and retention expiry.
  • Documentation
    • Updated TiDB HTTP API reference (stats dump endpoints/settings and numbering) to match the removed snapshot/history options.

@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/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. component/statistics sig/planner SIG: Planner labels Jul 16, 2026
@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: e0d33e77-d19e-48a0-8be2-f10d1864e67f

📥 Commits

Reviewing files that changed from the base of the PR and between 2ed4204 and 00e10c8.

📒 Files selected for processing (5)
  • .agents/skills/tidb-test-guidelines/references/executor-case-map.md
  • pkg/server/handler/optimizor/plan_replayer.go
  • pkg/sessionctx/variable/tests/variable_test.go
  • pkg/statistics/handle/storage/stats_read_writer.go
  • pkg/statistics/handle/storage/stats_read_writer_test.go
💤 Files with no reviewable changes (1)
  • .agents/skills/tidb-test-guidelines/references/executor-case-map.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/statistics/handle/storage/stats_read_writer.go

📝 Walkthrough

Walkthrough

The PR removes historical statistics generation and snapshot dumping across TiDB. It simplifies statistics storage APIs, plan replayer behavior, HTTP handlers, compatibility variables, metrics, dashboards, documentation, bootstrap wiring, and related tests while retaining cleanup of legacy history rows.

Changes

Historical statistics removal

Layer / File(s) Summary
Storage and execution APIs
pkg/statistics/handle/..., pkg/executor/..., br/pkg/restore/...
Storage interfaces no longer accept history sources or return historical versions; analyze, DDL, flush, and restore paths are updated accordingly.
Workers and compatibility state
pkg/domain/..., pkg/session/..., pkg/sessionctx/...
Historical-stats workers and session state are removed; legacy variables remain as warning-producing compatibility settings.
Plan replayer and HTTP serving
pkg/planner/core/..., pkg/util/replayer/..., pkg/server/...
Plan replayer dumps always use current statistics, legacy clauses produce warnings, snapshot statistics routes are removed, and capture bundles stream without historical-stat injection.
Metrics, docs, and tests
pkg/metrics/..., docs/tidb_http_api.md, pkg/**/BUILD.bazel, pkg/**/_test.go
Historical-stat metrics and dashboard panels are deleted, API documentation is renumbered, and tests/build targets are adjusted for the removed feature.

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

Possibly related PRs

Suggested labels: release-note-none

Poem

I’m a rabbit with stats in my paws,
Pruning old trails and historical claws.
Fresh plans now hop, current rows gleam,
Legacy flags whisper in a warning dream.
The dashboards fade, the paths run light—
Sniff, sniff—clean code takes flight!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning docs/tidb_http_api.md adds several unrelated API/settings entries beyond historical stats removal. Split unrelated documentation edits into a separate PR, or remove them if they are not required for the historical stats fix.
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: removing the historical stats feature.
Description check ✅ Passed The description includes the issue number, problem summary, change summary, checklist, and release note.
Linked Issues check ✅ Passed The PR removes RecordHistoricalStatsToStorage and related plumbing, directly addressing the memory issue in #52826.
✨ 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.

0xPoe added 2 commits July 16, 2026 14:12
…residue

Follow-ups to the historical stats feature removal:

- Fix ClearOutdatedHistoryStats returning after its first 50-row batch and
  deriving the batch count from the wrong table: count and drain
  mysql.stats_meta_history and mysql.stats_history independently, and add
  regression tests for both kept legacy drain paths.
- Warn when serving pre-upgrade capture_replayer_*.zip files, which no
  longer get download-time stats injection.
- Delete residue orphaned by the removal: unused plan replayer test helpers,
  the stale panic-when-record-historical-stats-meta failpoint enable, the
  Snapshot route constant, the removed endpoint's entry in
  docs/tidb_http_api.md, the source parameter on the stats save APIs and the
  StatsMetaHistorySource* constants, write-only
  SessionVars.EnableHistoricalStats and subscriber.statsCache, dead uint64
  version returns, and the EnableHistoricalStatsForCapture atomic and hooks.
- Make tidb_enable_historical_stats and
  tidb_enable_historical_stats_for_capture append a removed-feature warning
  when set to ON, and correct the tidb_historical_stats_duration comment,
  which still tunes the legacy drain retention.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

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

Inline comments:
In `@pkg/statistics/handle/storage/stats_read_writer.go`:
- Line 119: Update the error return in the stats metadata version update path to
wrap and preserve the original err, using context-neutral wording such as a
general stats-save failure rather than referencing analyze-result saving. Keep
the actionable retry guidance while ensuring the underlying cause remains
available to callers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: f544f1e2-19d2-4430-a3be-76acba5fec01

📥 Commits

Reviewing files that changed from the base of the PR and between 94b834d and 8873b70.

📒 Files selected for processing (78)
  • br/pkg/restore/snap_client/pipeline_items.go
  • br/pkg/restore/snap_client/pipeline_items_test.go
  • docs/tidb_http_api.md
  • pkg/domain/BUILD.bazel
  • pkg/domain/domain.go
  • pkg/domain/extract.go
  • pkg/domain/historical_stats.go
  • pkg/domain/metrics/metrics.go
  • pkg/domain/plan_replayer.go
  • pkg/domain/plan_replayer_dump.go
  • pkg/domain/plan_replayer_test.go
  • pkg/executor/BUILD.bazel
  • pkg/executor/analyze.go
  • pkg/executor/analyze_global_stats.go
  • pkg/executor/analyze_worker.go
  • pkg/executor/builder.go
  • pkg/executor/historical_stats_test.go
  • pkg/executor/plan_replayer.go
  • pkg/executor/test/loaddatatest/load_data_test.go
  • pkg/executor/test/planreplayer/plan_replayer_test.go
  • pkg/metrics/grafana/tidb.json
  • pkg/metrics/metrics.go
  • pkg/metrics/nextgengrafana/tidb_with_keyspace_name.json
  • pkg/metrics/nextgengrafana/tidb_worker.json
  • pkg/metrics/stats.go
  • pkg/parser/ast/misc.go
  • pkg/parser/ast/misc_test.go
  • pkg/parser/parser.go
  • pkg/parser/parser.y
  • pkg/planner/core/BUILD.bazel
  • pkg/planner/core/common_plans.go
  • pkg/planner/core/planbuilder.go
  • pkg/server/BUILD.bazel
  • pkg/server/handler/optimizor/BUILD.bazel
  • pkg/server/handler/optimizor/optimize_trace.go
  • pkg/server/handler/optimizor/plan_replayer.go
  • pkg/server/handler/optimizor/plan_replayer_test.go
  • pkg/server/handler/optimizor/statistics_handler.go
  • pkg/server/handler/optimizor/statistics_handler_test.go
  • pkg/server/handler/util.go
  • pkg/server/http_handler.go
  • pkg/server/http_status.go
  • pkg/session/session.go
  • pkg/sessionctx/vardef/tidb_vars.go
  • pkg/sessionctx/variable/session.go
  • pkg/sessionctx/variable/sysvar.go
  • pkg/sessionctx/variable/sysvar_test.go
  • pkg/statistics/BUILD.bazel
  • pkg/statistics/handle/BUILD.bazel
  • pkg/statistics/handle/ddl/BUILD.bazel
  • pkg/statistics/handle/ddl/ddl.go
  • pkg/statistics/handle/ddl/subscriber.go
  • pkg/statistics/handle/globalstats/global_stats.go
  • pkg/statistics/handle/handle.go
  • pkg/statistics/handle/handletest/BUILD.bazel
  • pkg/statistics/handle/handletest/handle_test.go
  • pkg/statistics/handle/handletest/lockstats/BUILD.bazel
  • pkg/statistics/handle/handletest/lockstats/lock_table_stats_test.go
  • pkg/statistics/handle/history/BUILD.bazel
  • pkg/statistics/handle/history/history_stats.go
  • pkg/statistics/handle/metrics/metrics.go
  • pkg/statistics/handle/storage/BUILD.bazel
  • pkg/statistics/handle/storage/dump_test.go
  • pkg/statistics/handle/storage/gc.go
  • pkg/statistics/handle/storage/gc_test.go
  • pkg/statistics/handle/storage/json.go
  • pkg/statistics/handle/storage/save.go
  • pkg/statistics/handle/storage/stats_read_writer.go
  • pkg/statistics/handle/storage/stats_read_writer_test.go
  • pkg/statistics/handle/types/interfaces.go
  • pkg/statistics/handle/updatetest/update_test.go
  • pkg/statistics/handle/usage/BUILD.bazel
  • pkg/statistics/handle/usage/session_stats_collect.go
  • pkg/statistics/handle/util/util.go
  • pkg/statistics/integration_test.go
  • pkg/statistics/util/json_objects.go
  • pkg/testkit/mockstore.go
  • pkg/util/replayer/replayer.go
💤 Files with no reviewable changes (37)
  • pkg/server/BUILD.bazel
  • pkg/metrics/metrics.go
  • pkg/server/handler/optimizor/optimize_trace.go
  • pkg/planner/core/BUILD.bazel
  • pkg/domain/BUILD.bazel
  • pkg/domain/historical_stats.go
  • pkg/server/handler/util.go
  • pkg/statistics/handle/handle.go
  • pkg/executor/test/loaddatatest/load_data_test.go
  • pkg/statistics/handle/history/BUILD.bazel
  • pkg/statistics/handle/BUILD.bazel
  • pkg/statistics/handle/handletest/lockstats/BUILD.bazel
  • pkg/executor/analyze_global_stats.go
  • pkg/metrics/grafana/tidb.json
  • pkg/metrics/stats.go
  • pkg/statistics/handle/updatetest/update_test.go
  • pkg/statistics/handle/handletest/handle_test.go
  • pkg/server/handler/optimizor/statistics_handler.go
  • pkg/executor/test/planreplayer/plan_replayer_test.go
  • pkg/executor/BUILD.bazel
  • pkg/statistics/handle/ddl/BUILD.bazel
  • pkg/testkit/mockstore.go
  • pkg/statistics/handle/globalstats/global_stats.go
  • pkg/metrics/nextgengrafana/tidb_worker.json
  • pkg/statistics/handle/usage/BUILD.bazel
  • pkg/sessionctx/variable/session.go
  • pkg/statistics/handle/handletest/lockstats/lock_table_stats_test.go
  • pkg/domain/metrics/metrics.go
  • pkg/metrics/nextgengrafana/tidb_with_keyspace_name.json
  • pkg/planner/core/planbuilder.go
  • pkg/statistics/handle/history/history_stats.go
  • pkg/server/http_status.go
  • pkg/statistics/handle/storage/dump_test.go
  • pkg/executor/historical_stats_test.go
  • pkg/server/handler/optimizor/plan_replayer_test.go
  • pkg/executor/analyze.go
  • pkg/statistics/handle/storage/json.go

Comment thread pkg/statistics/handle/storage/stats_read_writer.go Outdated
… as a no-op

Keep accepting `PLAN REPLAYER DUMP ... WITH STATS AS OF TIMESTAMP ...` for
compatibility after the historical stats feature removal: the clause is
ignored, the dump contains current statistics, and a warning is reported.
The warning is appended after the dump finishes because the internal SQL
executed while dumping resets the session's statement context, so a
plan-building-time warning would not survive to SHOW WARNINGS.
@0xPoe 0xPoe force-pushed the poe/remove-historical-stats-master branch from 8873b70 to 0ce1485 Compare July 16, 2026 12:27
@codecov

codecov Bot commented Jul 16, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 33.12883% with 109 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.6195%. Comparing base (d573e28) to head (00e10c8).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@               Coverage Diff                @@
##             master     #69889        +/-   ##
================================================
- Coverage   76.3206%   75.6195%   -0.7012%     
================================================
  Files          2041       2085        +44     
  Lines        559973     581826     +21853     
================================================
+ Hits         427375     439974     +12599     
- Misses       131697     139707      +8010     
- Partials        901       2145      +1244     
Flag Coverage Δ
integration 45.6941% <33.1288%> (+5.9889%) ⬆️

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

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

The historical stats removal left the DDL subscriber helper methods and
buildPlanReplayer with receivers that are no longer referenced, which
fails bazel nogo's revive unused-receiver check; use anonymous receivers.
Also sync pkg/bindinfo/tests shard_count with the gazelle output required
by check-bazel-prepare.
@ti-chi-bot

ti-chi-bot Bot commented Jul 16, 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, nolouch, terry1purcell, yangkeao 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

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

Labels

component/statistics release-note Denotes a PR that will be considered when it comes time to generate release notes. sig/planner SIG: Planner size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RecordHistoricalStatsToStorage used too much memory

1 participant