确认OOM Killer杀MySQL是首要步骤:执行dmesg -T | grep -i "killed process" | grep mysqld,若输出含“Kill process X (mysqld)”,即为铁证;再交叉验证/var/log/messages中oom_kill记录及时间戳,并以MemAvailable为准校准真实可用内存,而非free -h的used值。

直接看 dmesg -T | grep -i "killed process",如果输出里有 mysqld 和 Out of memory,那基本就是 OOM Killer 下的手——不是 MySQL 崩溃,是被系统“处决”了。接下来要做的不是立刻调 innodb_buffer_pool_size,而是分三路交叉验证:系统真实可用内存、MySQL 配置叠加效应、运行时内存分布。
确认是不是真被 OOM Killer 杀的
很多人跳过这步就改配置,结果白忙活。必须先坐实“杀因”,否则可能压根不是内存问题。
- 执行
dmesg -T | grep -i "killed process" | grep mysqld,看到类似Kill process 12345 (mysqld) score 956就是铁证 - 检查
/var/log/messages或/var/log/syslog,搜oom_kill或badness,注意时间戳是否和 MySQL 崩溃时间对得上 - 如果没匹配到,别硬往内存上靠——可能是磁盘满(
df -h)、配置语法错误(mysqld --validate-config)、或信号中断(journalctl -u mysqld | tail -20)
查系统真实可用内存,别信 free -h 的 used
free -h 里的 used 包含大量可回收缓存,误导性极强;真正能分给 MySQL 的只有 available 列,它反映内核当前能立刻分配的物理内存。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 运行
cat /proc/meminfo | grep MemAvailable,这个值才是你敢设innodb_buffer_pool_size的硬上限 - 对比
ps aux --sort=-%mem | head -5,确认mysqld是否真排第一;如果不是,先处理那个 Python/Java 进程 - 云主机(如阿里云共享型、AWS t3)的
MemTotal常虚高,MemAvailable才是唯一可信指标
看 MySQL 配置里哪些参数会“叠buff”式吃内存
innodb_buffer_pool_size 是明面上的大头,但多个连接级缓冲叠加后,总内存 = 连接数 × 单连接缓冲 + 全局缓冲,很容易失控。
-
sort_buffer_size、join_buffer_size、read_buffer_size:每个连接独占,不是全局共享。设成 4M 且有 500 个活跃连接,光这三项就吃掉 6GB -
tmp_table_size和max_heap_table_size:取小值,控制内存临时表上限。设太大(如 512M)+ 复杂 GROUP BY 查询多 → 单查询就占几百 MB -
performance_schema:默认开启,高并发下自身开销可达 1–2GB;若不依赖深度诊断,可设performance_schema=OFF(需重启) -
table_open_cache+table_open_cache_instances:高并发下每个 instance 都缓存一份表结构;若大量触发器/存储过程,table_open_cache_instances设太高(如 16)会额外吃内存
用 performance_schema 查实时内存分布和碎片迹象
光看配置是静态的,真正要命的是运行中内存怎么分、有没有卡住不释放。
- 执行:
SELECT SUBSTRING_INDEX(event_name,'/',2) AS code_area, SUM(CURRENT_NUMBER_OF_BYTES_USED) AS used FROM performance_schema.memory_summary_global_by_event_name GROUP BY code_area ORDER BY used DESC;
重点关注innodb、sql、memory/heap三块是否异常偏高 - 特别盯
memory/sql/sp_head::main_mem_root:这是存储过程/游标独占内存,不属缓冲池管理,未显式CLOSE或异常退出就会一直挂着,多个并发调用会线性累积 - 查
SHOW ENGINE INNODB STATUS\G里Innodb_buffer_pool_wait_free:如果 > 0,说明 page cleaner 已经跟不上淘汰速度,buffer pool 卡死在极限边缘
最容易被忽略的是:OOM 往往不是单点参数问题,而是 innodb_buffer_pool_size + 连接缓冲 + performance_schema + 存储过程内存 四者叠加的结果。调一个不管用,必须同步压住所有内存源;另外,MemAvailable 比 free -h 的任何一列都重要,但它在云主机上波动大,建议每小时采样一次做基线比对。

















