关于表 cluster_statements_summary_history 和 cluster_statements_summary的疑问

【TiDB 使用环境】
测试环境
【TiDB 版本】
v8.5.6
【问题】
根据官档 Statement Summary Tables | 平凯数据库 的说明,我之前一直理解 cluster_statements_summary 的数据会在采样时间参数 tidb_stmt_summary_refresh_interval 后将采样的数据库清空并复制到 cluster_statements_summary_history 表。换句话说:默认参数配置下,11:18 分查询cluster_statements_summary 的数据不应该出现在 cluster_statements_summary_history 表(采样时间段是 11:00 到 11:30),但是今天突然发现:11:18 分查询 cluster_statements_summary_history 表,也可以查看 cluster_statements_summary 的数据,这如何理解?

【示例】

cluster_statements_summary_history 里的数据是过去某个时刻的快照

建议先检查下 tidb_stmt_summary_refresh_interval 的实际值,用 show config where name like '%tidb_stmt_summary_refresh_interval%'; 确认。默认是1800秒(30分钟),但可能被改过,比如设成600秒(10分钟),那11:18分看到11:00-11:30的数据就正常了,因为刷新周期内数据是实时累积的。

你理解的"summary 清掉 + history 拿到"是错的,实际是"同一份数据,两个窗口读"**。

打个比方:内存里有一个滑动窗口(一长条),每个 30 分钟切一段,按时间从左往右排队。

  • cluster_statements_summary = 只看最右边那段(正在进行的那一段)
  • cluster_statements_summary_history = 整条都看(包括最右边那段)

所以 11:18 这个时刻,最右边那段就是 [11:00, 11:30],两边都看得到

1 个赞

并不是刷新时刻一次性复制整段窗口数据进 history + 清空当前表

官方原文机制(v8.5 与 v7.x 逻辑完全一致):

  1. statements_summary(当前表):内存实时累加当前窗口([SUMMARY_BEGIN_TIME, SUMMARY_END_TIME],长度 = refresh_interval,默认 30min)所有 SQL 指标,持续写入、实时聚合
  2. tidb_stmt_summary_refresh_interval = 1800s 只是当前窗口的生命周期
  • 每到整点窗口边界(11:00、11:30、12:00):把整个窗口的最终聚合快照写入 history,之后清空当前 summary 内存,开启下一个全新窗口(11:30~12:00)。
  • 窗口运行中(11:00~11:30 区间内任意时刻,比如 11:18):当前窗口数据只存在 summary 里,理论上 history 不会出现本条窗口记录

应该是Statements Summary的内存结构有变化,cluster_statements_summary 并不是“先写入 history、再独删除”的两段式逻辑。两张表读的是同一个summary 链表,只是取的位置不同。
cluster_statements_summary:取最新窗口
cluster_statements_summary_history :最近 N 个历史窗口

  1. 数据链表(util/stmtsummary/stmt_summary.go)
type StmtSummaryByDigest struct {
    // ...
    history []*StmtSummaryByDigestWindow   // 多个连续时间窗口的汇总快照
    // ...
}
  1. CLUSTER_STATEMENTS_SUMMARY的查询(executor/infoschema_reader.go)
func (e *memtableRetriever) setDataForStatementsSummary(...) {
    for _, ssbd := range stmtsummary.StmtSummaryByDigestMap {
        win := ssbd.CurrentWindow()          // 返回 history[len(history)-1]
        // 用 win 构造一行数据...
    }
}
  1. CLUSTER_STATEMENTS_SUMMARY_HISTORY的查询(executor/infoschema_reader.go)
func (e *memtableRetriever) setDataForStatementsSummaryHistory(...) {
    for _, ssbd := range stmtsummary.StmtSummaryByDigestMap {
        for _, win := range ssbd.HistoryWindows() { // 从最旧到最新,包含当前窗口
            // 每个窗口生成一行...
        }
    }
}

tidb_stmt_summary_refresh_interval 是默认值 1800s

我的疑问就是这个:

当前窗口数据只存在 summary 里,理论上 history 不会出现本条窗口记录

新版本 statement summary 对 history 的写入/可见策略可能与旧文档「整窗结束才搬运」不完全一致:当前窗数据可能被提前归档或查询视图做了合并展示。以实际 tidb_stmt_summary_* 参数和 EXPLAIN/表数据时间为准,不要只按旧理解硬套。可对比同一 digest 在两表的 begin/end time 字段确认是否重叠窗。

此话题已在最后回复的 7 天后被自动关闭。不再允许新回复。