MySQL主库内存规划需统筹缓冲池、CPU特性与可用内存:先按InnoDB数据量设innodb_buffer_pool_size下限(如16GB数据设20–24GB),预留热数据增长;OLTP场景每核预留100–200MB连接/排序内存,32核需3–6GB;启动前确保free -h的available ≥ 缓冲池+2GB;注意chunk对齐(默认128MB×8实例=1GB粒度);并预留10%–15%内存给临时表、线程栈等;最终以命中率≥95%、iostat await稳定、INNODB STATUS无LRU异常为验证标准。

主库内存规划不能只看缓冲池,得把 CPU 特性、工作负载类型和内存实际可用量串起来看。缓冲池(innodb_buffer_pool_size)是核心,但它只是内存分配的起点,不是终点。
先按数据量定缓冲池下限
别一上来就套“70%物理内存”。先查真实 InnoDB 数据体积:
- 执行:SELECT CEILING(SUM(data_length + index_length) / 1024 / 1024) AS mb FROM information_schema.tables WHERE engine='InnoDB';
- 结果 ≤ 2GB → 缓冲池设 2–4GB 足够,再大没意义
- 结果在 10–25GB → 建议设为该值的 1.2–1.5 倍(比如 16GB 数据,设 20–24GB),预留热数据增长与索引结构开销
- 这个值必须略大于热数据(高频访问的表+索引),不是全量数据
再扣掉 CPU 和系统竞争内存
CPU 核心数和调度方式直接影响内存使用效率:
- OLTP 主库(高并发小事务):建议关闭超线程,CPU 核心数控制在 16–48 个;每核需约 100–200MB 额外内存用于连接线程、排序缓存、日志缓冲等,32 核就要预留 3–6GB
- OLAP 或混合主库:可开启超线程,但要监控 vm.swappiness;若频繁 swap,说明缓冲池挤占了 OS 缓存,应下调 2–4GB
- 用 free -h 看 available 列,不是 free 列;主库启动前必须确保 available ≥ 缓冲池设定值 + 2GB(OS 最低保障)
最后对齐 chunk 规则并留弹性空间
MySQL 不接受任意数值,必须满足底层内存分配约束:
- 生效值 = innodb_buffer_pool_chunk_size × innodb_buffer_pool_instances 的整数倍
- 默认 chunk 是 128MB,实例数常见为 8 → 最小调整单位是 1GB;想设 23GB?系统会自动取整到 24GB 或 22GB
- 查当前规则:SELECT @@innodb_buffer_pool_chunk_size, @@innodb_buffer_pool_instances;
- 主库建议预留 10%–15% 内存给临时表(tmp_table_size)、连接线程栈、binlog cache 和后台线程(如 purge、change buffer merge)
验证是否真正匹配 CPU 与内存协同
配完不等于生效,得看运行态反馈:
- 命中率:SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read%'; 计算 (1 − Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests),持续低于 95% 才考虑加缓冲池
- 磁盘读压力:iostat -x 1 观察 %util 和 await,若缓冲池已够大但 await 仍高,问题在磁盘或 SQL,不是内存
- CPU 等待:若 SHOW ENGINE INNODB STATUS 中 “BUFFER POOL AND MEMORY” 显示大量 free buffers 或 old database pages 持续不老化,说明缓冲池过大、LRU 效率下降,反而拖慢 CPU 处理速度


















