INFORMATION_SCHEMA.INNODB_BUFFER_PAGE结果不准或为空,因其依赖手动触发的buffer pool dump快照、非实时、MySQL 8.0.21+才默认启用,且含大量系统页干扰;推荐优先使用sys.schema_table_statistics_with_buffer视图结合INNODB_METRICS和performance_schema分析真实热点。

查 INFORMATION_SCHEMA.INNODB_BUFFER_PAGE 表时为什么结果不准或为空?
直接查 INFORMATION_SCHEMA.INNODB_BUFFER_PAGE 是最直觉的做法,但它有硬限制:默认关闭、需 innodb_buffer_pool_dump_at_shutdown=ON 或手动触发 dump,且只反映最近一次 dump 时的快照,不是实时状态。更关键的是,MySQL 8.0.21+ 才默认启用该表(旧版本需显式开启 innodb_buffer_pool_dump_now),而即使开启,每页记录还包含大量系统页(如 undo、insert buffer),干扰真实业务表统计。
实操建议:
- 先确认是否可用:
SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE;若返回 0 或报错Table 'INFORMATION_SCHEMA.INNODB_BUFFER_PAGE' doesn't exist,说明未启用或权限不足(需PROCESS权限) - 临时启用(仅限调试):
SET GLOBAL innodb_buffer_pool_dump_now = ON;,再等几秒后查;但注意这会引发 I/O 小高峰 - 生产环境慎用——该表扫描开销大,且单次 dump 后不自动刷新,不能代表当前热点
用 sys.schema_table_statistics_with_buffer 快速定位高缓冲占用表
MySQL 自带的 sys 库视图是更稳妥的选择,它聚合了 INNODB_BUFFER_PAGE + TABLES + COLUMNS 信息,并过滤掉系统页,按表维度汇总缓冲页数和估算内存占用。
执行这条语句即可:
SELECT object_schema, object_name,
allocated, data, pages, pages_hashed, pages_old, rows_cached
FROM sys.schema_table_statistics_with_buffer
WHERE object_schema NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys')
ORDER BY allocated DESC LIMIT 10;说明:
-
allocated是估算的字节数(含页头、碎片等),比单纯算pages * 16K更准 -
pages是该表实际驻留 Buffer Pool 的页面数,可直接对比大小 - 若
rows_cached显著高于实际行数,可能说明该表被频繁全表扫描或索引覆盖不全
INFORMATION_SCHEMA.INNODB_METRICS 能否辅助判断缓冲压力?
不能直接看出哪张表占得多,但能验证 Buffer Pool 是否真的吃紧——比如 buffer_pool_reads(从磁盘读取页数)持续上升,而 buffer_pool_read_requests 稳定,说明命中率下降,此时再回溯找表才有意义。
关键指标检查命令:
SELECT name, SUBSTRING(comment, 1, 50) AS comment, count
FROM INFORMATION_SCHEMA.INNODB_METRICS
WHERE name IN ('buffer_pool_reads', 'buffer_pool_read_requests', 'buffer_pool_wait_free');解读:
- 命中率 ≈
(buffer_pool_read_requests - buffer_pool_reads) / buffer_pool_read_requests,低于 95% 就该关注 -
buffer_pool_wait_free非零说明有线程在等空闲页,可能 Buffer Pool 太小或有大表反复刷入刷出 - 这些指标本身不关联表名,只是“要不要深入查表”的开关信号
真正想看实时热表?得结合 performance_schema + 查询模式分析
Buffer Pool 占用是结果,访问频率才是原因。如果 sys 视图显示某张表长期高占位,下一步应查它是否被高频访问或存在低效查询。
示例:查最近 1 小时内扫描行数最多的表(需已开启 performance_schema 并配置相关 consumers):
SELECT OBJECT_SCHEMA, OBJECT_NAME, COUNT_READ, SUM_NUMBER_OF_BYTES_READ
FROM performance_schema.table_io_waits_summary_by_table
WHERE OBJECT_SCHEMA NOT IN ('mysql', 'sys', 'information_schema', 'performance_schema')
ORDER BY COUNT_READ DESC LIMIT 5;注意点:
- 该统计依赖
events_waits_history_long或 consumer 开启,生产库常默认关闭部分项,需提前确认:SELECT * FROM performance_schema.setup_consumers WHERE NAME LIKE '%table%'; -
COUNT_READ高但SUM_NUMBER_OF_BYTES_READ低,可能是索引扫描;反之则大概率是全表扫——后者更容易把大表塞满 Buffer Pool - 单看这一项还不够,要和慢日志、
EXPLAIN结合,否则容易误判:比如一张小表被 JOIN 一百万次,也会显得“热门”
Buffer Pool 表级占用没有银弹式实时视图,sys.schema_table_statistics_with_buffer 是平衡准确性和可用性的起点,但必须搭配访问行为分析才能定位根因——否则你优化的可能只是缓存残留,不是真实瓶颈。


















