MyISAM的“低内存”实为OS page cache占用,InnoDB的高RSS才反映真实内存消耗;需同时监控RSS与/proc/pid/maps中mapped file总量,单看任一指标均会误判。

不能只看mysqld进程RSS值——MyISAM的“低内存”是把账记到OS page cache上,InnoDB的高RSS才是真实占用。
为什么ps aux看到的内存增长不等于真实增量
MyISAM把数据全扔给操作系统缓存,mysqld进程自身RSS可能只有200MB,但/proc/$(pgrep mysqld)/maps里mapped file区域可能吃掉12GB;InnoDB则把热页全塞进innodb_buffer_pool_size,RSS直接体现为缓冲池大小。两者叠加才算总内存开销。
常见误判:迁移后RSS从300MB涨到4.5GB,就认定“多占了4.2GB”,其实OS层mapped file可能从12GB降到了1.8GB——真实增量远小于此。
- 查MyISAM索引实际缓存:运行
SHOW STATUS LIKE 'Key_blocks_used'×key_cache_block_size - 查OS层mapped总量:
cat /proc/$(pgrep mysqld)/maps | awk '$6 ~ /\[.*\]/ {sum += $2} END {print sum/1024/1024 " MB"}' - 查InnoDB缓冲池使用率:
SHOW ENGINE INNODB STATUS\G,找Buffer pool size和Free buffers
innodb_buffer_pool_size设多少才不算过量
沿用MyISAM时代的key_buffer_size=256M配innodb_buffer_pool_size=256M,等于让InnoDB裸盘扫描——QPS暴跌、慢查询激增基本由此而来。
- Linux下建议设为物理内存的50%–75%,但必须预留≥2GB给OS及其他进程(尤其开了
tmp_table_size或sort_buffer_size时) - 检查是否被
innodb_dedicated_server=ON干扰:SHOW VARIABLES LIKE 'innodb_dedicated_server',混部环境务必关掉 - 确保值是
innodb_buffer_pool_chunk_size×innodb_buffer_pool_instances的整数倍(默认128MB × 8 = 1024MB),否则启动时自动向下取整 - 改完重启后立刻查
Buffer pool hit rate,持续低于99.5%就得再调大
key_buffer_size不降会抢走真实内存
MyISAM时代设的key_buffer_size=256M在InnoDB为主力后毫无意义,反而和缓冲池争抢物理内存,可能触发swap或OOM。这不是“留着也无害”,而是明确的资源浪费。
- 迁移完成后立即将
key_buffer_size从256M降到32M甚至8M - 若库中仍有少量MyISAM表,按实际索引大小估算:
SELECT SUM(index_length) FROM information_schema.tables WHERE engine='MyISAM',设为该值的1.2倍即可 - 别忽略
query_cache_size(MySQL 8.0+已废弃),旧配置残留会白占内存
真正容易被忽略的是:迁移后必须同时监控innodb_buffer_pool_size使用率和OS层mapped file总量,单看任一指标都会误判。缓冲池没填满却RSS飙升?大概率是OS page cache还没释放旧MyISAM文件映射——等几个小时再看,或手动echo 1 > /proc/sys/vm/drop_caches(仅限测试环境)。


















