MySQL 5.7开启innodb_buffer_pool_load_at_startup后,BP预热成为缓解重启性能雪崩的关键机制,但必须配合innodb_buffer_pool_dump_at_shutdown=1在正常关闭时生成有效dump文件,否则加载无效;dump精度由innodb_buffer_pool_dump_pct控制,默认25%兼顾效率与命中率。

innodb_buffer_pool_load_at_startup 开启后,MySQL 5.7 的 BP 预热不再是“可有可无”的附加操作,而是能直接缓解重启后性能雪崩的关键机制——前提是配置正确、dump 文件有效、且实例曾正常关闭。
预热依赖 innodb_buffer_pool_dump_at_shutdown=1 是否生效
预热不是单靠启动时加载就能起作用的。它必须配合关机前的 dump 行为:innodb_buffer_pool_dump_at_shutdown=1 才会在 MySQL 正常关闭(SIGTERM 或 mysqladmin shutdown)时,把当前 buffer pool 中的热页写入磁盘文件(默认是 ib_buffer_pool,路径由 innodb_buffer_pool_filename 控制)。如果 MySQL 是被 kill -9 强杀、宕机或异常退出,这个文件就不会生成或不完整,启动时加载就等于加载空数据。
- 检查 dump 是否成功:启动后执行
SELECT * FROM INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS\G,看pages_total和pages_data是否快速接近预期值;同时确认innodb_buffer_pool_load_status变量是否显示 “Buffer pool(s) load completed at …” - dump 文件位置默认在 datadir 下,但可通过
innodb_buffer_pool_filename=/path/to/ib_buffer_pool显式指定,注意路径需 MySQL 进程有读写权限 - MySQL 5.7 默认启用
innodb_buffer_pool_dump_at_shutdown和innodb_buffer_pool_load_at_startup,但很多生产环境仍沿用旧配置,实际是关闭状态
innodb_buffer_pool_dump_pct 控制预热“精度”而非“开关”
MySQL 5.6 是全量 dump,而 5.7 引入 innodb_buffer_pool_dump_pct(默认 25),只 dump 每个 buffer pool instance 中最热的前 N% 页面。这不是为了“省空间”,而是权衡 dump/load 时间与命中率:
- 设为 100% 能最大程度还原重启前状态,但 dump 文件大、写盘慢,可能拖长关闭时间;load 时也更耗内存和 I/O
- 设为 25% 是平衡点:实测多数业务中,前 25% 页面覆盖了 70%+ 的热点访问,且 dump/load 延迟可控
- 该参数仅影响 dump 阶段,不影响 load 阶段——启动时会尽力加载所有 dump 出来的页,不管 pct 是多少
- 不能动态修改,需写入 my.cnf 并重启才生效
预热失败常见现象及验证方式
你以为开了预热,其实没生效,典型表现包括:
- 启动后
SHOW ENGINE INNODB STATUS\G中 “Free buffers” 数量长期居高不下(比如 >80%),说明 buffer pool 大量空闲,未加载有效页 -
SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME = 'Innodb_buffer_pool_read_requests'和'Innodb_buffer_pool_reads'的比值在前 5 分钟内远低于日常水平(如 < 90%),说明大量请求仍走磁盘 - 查询
information_schema.INNODB_BUFFER_POOL_PAGES_DATA,发现 pages 数量增长极慢,甚至数分钟后仍只有几百页 - 日志里出现 “Buffer pool load skipped because buffer pool is not yet initialized” —— 这说明
innodb_buffer_pool_load_at_startup被提前触发,但 buffer pool 尚未完成初始化,常见于配置了过小的innodb_buffer_pool_size或内存不足
真正影响预热效果的隐藏因素
预热能否“立竿见影”,取决于三个容易被忽略的底层条件:
-
innodb_buffer_pool_instances必须 ≥ 1,且不能大于 CPU 核心数太多;若设为 1,dump/load 是单线程;若设为 8,dump 会并发写 8 个分片,load 也会并发读,但实例数过多反而增加锁竞争 - dump 文件内容基于 LRU 管理器的热度排序,但 InnoDB 在 5.7 中对 LRU 实现做了优化(引入 young/old sublist),所以 dump 出来的“热页”更贴近真实访问模式,比 5.6 更准——但这只在你没禁用
innodb_old_blocks_time的前提下成立 - 预热加载的是 page id + space id,不是表名或 SQL;如果某张表在重启前被大量访问,但其索引页恰好不在 top-pct 热度范围内,它就不会被预热——这意味着预热无法替代应用层冷启动流量控制
预热不是魔法开关,它只负责把上次关机时的内存快照尽可能还原。真正决定“热不热”的,是你的业务访问模式是否稳定、是否允许 MySQL 正常关闭、以及 buffer pool 配置是否匹配物理内存与负载特征。任何一环断裂,预热就退化成一个安静的日志条目。


















