TiDB 恢复备份后如何用 REFRESH STATS 命令将统计信息重新加载到内存
【免费下载链接】tidbTiDB is built for agentic workloads that grow unpredictably, with ACID guarantees and native support for transactions, analytics, and vector search. No data silos. No noisy neighbors. No infrastructure ceiling.项目地址: https://gitcode.com/GitHub_Trending/ti/tidb
TiDB 集群启动时会把统计信息加载到每个 TiDB 节点的内存中。当 BR 工具在集群运行期间完成统计信息相关表的物理恢复(backup and restore)后,节点内存中仍然是恢复前的统计信息,查询无法及时用上恢复回来的最新统计。设计文档给出的替代方案是整体重启 TiDB 节点,让启动流程重新初始化统计,但这显然不方便。REFRESH STATS命令就是为解决这个问题引入的:它可以在不重启集群、不重新执行ANALYZE的情况下,强制把指定表的统计信息重新加载到内存,BR 工具恢复完成后即可用它触发刷新。该命令同样适用于排查内存统计信息异常的场景(见 设计文档)。
命令语法与各参数含义
命令格式如下(来自设计文档的 guide-level 说明):
REFRESH STATS <TARGETS> [FULL | LITE] [CLUSTER];文档给出的示例:
REFRESH STATS db1.tbl1, tbl2, db2.*, *.* FULL CLUSTER;各部分的取值规则:
TARGETS是逗号分隔的目标列表,支持四种形式:tab1:当前 schema 下的tab1表。注意如果未指定当前数据库,解析阶段会直接报ErrNoDB错误,因此执行前先用USE <db>选定数据库,或者全部写成db.table形式(见 fillDefaultDBForStatsObjects);db1.tbl1:指定库下的具体表;db2.*:指定库下的所有表;*.*:集群内所有表。
FULL | LITE指定刷新统计信息的类型。省略时取配置项lite-init-stats(v7.10 引入)的值;显式写FULL等价于lite-init-stats=false,显式写LITE等价于lite-init-stats=true(见 executeRefreshStatsOnCurrentInstance);CLUSTER:设置后刷新发生在集群中所有 TiDB 实例上;不设置时只刷新当前连接的 TiDB 实例。因为统计信息存放在各 TiDB 节点的内存中,而用户可能只连到单个节点,所以跨节点刷新需要CLUSTER。其实现方式是仿照KILL语句,通过 coprocessor 框架把语句广播到所有 TiDB 节点(store type 设为 TiDB、server ID 设为 0,使每个 TiDB 节点各生成一个 coprocessor 任务)。
执行前置条件
- 集群已启动,BR 对统计信息表的恢复操作已经完成;
- 执行用户具备目标表的
SELECT权限;BR 工具则通过动态权限校验(设计文档写为 ADMIN_RESTORE,源码中的校验名称为 RESTORE_ADMIN,见 requireSelectOrRestoreAdminPrivForStatsObjects); - 确认没有其它统计初始化操作正在进行:设计文档 FAQ 明确,已有 init stats 操作在处理时会尽早返回错误,避免并发刷新把实现复杂化。
执行步骤
以恢复完db1和db2两个库的统计信息为例,用具备目标表SELECT权限的账号连接集群后执行:
REFRESH STATS db1.*, db2.* FULL CLUSTER;需要说明的参数选择:
- 目标写成
db.*或db.tbl形式可以不依赖当前数据库,跨节点广播时也会带上完整限定名,避免其它节点因当前库不同而漏刷(源码注释中明确解释了这一处理); - 是否需要
CLUSTER取决于你的访问方式:如果只刷新当前连接的实例,省略即可;集群多节点时建议加上,保证所有节点都加载最新统计; FULL/LITE按需指定。文档没有给出二者的性能取舍结论,如果你不确定,省略该选项让命令跟随lite-init-stats配置即可。
结果验证
- 命令正常返回、无报错,是刷新触发的基本信号。
- 执行端可在 TiDB 日志中确认刷新完成。源码中会记录如下日志(见 executeRefreshStats):
- 仅刷新当前实例:
Successfully refreshed statistics on the current instance - 集群广播:
Successfully broadcast query - 远端节点收到广播后执行:
Successfully refreshed statistics from remote
- 仅刷新当前实例:
- 如果指定的库或表全部不存在,命令不会报错,也不会做任何刷新(源码中的处理是记录
No valid database or table to refresh stats后直接返回),排查时应先确认目标库表名是否正确。
限制与注意事项
- 设计文档在 Impacts & Risks 中提示:该命令可能对 TiKV 上的在线负载产生性能影响,文档建议通过综合测试评估后再使用;生产集群中执行前应对影响有预期。
- 设计文档给出的超时参考公式为
Timeout = min((总表数 × 节点数) / 每分钟 1M 表 + 1 分钟缓冲, 15 分钟),并明确标注“该估算需要通过测试验证”(Unresolved Questions 中性能影响量级仍未定),因此不要把 15 分钟上限当作固定承诺值。 - 若集群中已存在部分统计信息,做物理恢复会丢弃它们并重建统计信息表;设计文档 FAQ 说明这种情况下应退回 stats JSON 备份恢复方案,而不是物理恢复。
延伸阅读:设计文档、执行器实现、权限与语句构建、语法定义。
【免费下载链接】tidbTiDB is built for agentic workloads that grow unpredictably, with ACID guarantees and native support for transactions, analytics, and vector search. No data silos. No noisy neighbors. No infrastructure ceiling.项目地址: https://gitcode.com/GitHub_Trending/ti/tidb
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考