innodb_buffer_pool_size 设多大合适
发布时间:2025-11-18 21:20       
更新时间:2025-11-19 03:25
这个参数没有标准数值,只有按机器角色划分的经验区间。buffer pool 是 InnoDB 自己的数据缓存,热点数据页和索引页都从这里过,命中了就不用读磁盘,它的大小直接决定数据库的表现。
## 一、为什么它最值得调
MySQL 默认的 buffer pool 只有 128M,对任何正式业务都明显偏小。磁盘随机读一次是毫秒级,内存命中是微秒级,差着三个数量级,命中率低就等于让每条查询都去磨磁盘。预算有限时,给数据库机器加内存,收益通常大于换 CPU。动它之前先看当前值:SHOW VARIABLES LIKE 'innodb_buffer_pool_size',新装的机器多半就是 128M 这个默认值。
## 二、专机给一半以上
数据库独占的机器,给物理内存的 50% 到 70%:16G 内存的机器给 10G 没问题;裸金属物理机 B4 这类独享资源、内存不被邻居抢占的机型,可以放心按上限配。机器上还跑着别的服务时,把它们的内存需求先列出来,剩下的才是数据库能拿的部分。写法:
```
[mysqld]
innodb_buffer_pool_size = 10G
```
8.0 支持在线调整,注意单位是字节:
```
SET GLOBAL innodb_buffer_pool_size = 10737418240;
```
## 三、混部要克制
数据库和应用同机部署时,给 30% 到 40% 就收手,剩下的留给操作系统缓存——文件读写靠 page cache 加速,把它挤干了,备份和日志写入反而变慢。容器环境注意 cgroup 限额和物理内存是两回事,配置按容器的限额算,不按宿主机算。小内存机器上跑个站点库,2G 内存给 512M、4G 给 1G 就够,按比例硬算没有意义。
## 四、命中率怎么观测
```
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read%';
```
命中率等于 1 减去 Innodb_buffer_pool_reads 除以 Innodb_buffer_pool_read_requests,前者是穿透到磁盘的次数。命中率长期低于九成九,要么内存不够,要么数据集确实太大,加内存或做数据归档,二选一。再看一眼 Innodb_buffer_pool_wait_free,这个数持续增长说明写压力也在排队,先查磁盘再谈调参。
调这个参数之前,先想清楚这台机器为谁服务。角色定下来,数值基本就定下来了,剩下的交给命中率曲线验证。调整一次只动一个参数,观察三天再动下一个,同时改两个,出了问题分不清原因。