MySQL 报资源不足错误,不是直接调大参数就能解决的——得先确认是哪类资源真不够,否则盲目调参可能让问题更糟。
看清楚报错具体是哪类资源:内存、连接数还是文件句柄?
MySQL 的“资源不足”是笼统说法,实际对应不同错误信息和底层机制:
ERROR 2003 (HY000): Can't connect to MySQL server或
Too many connections→ 通常是
max_connections耗尽,或系统级连接限制(如
ulimit -n)触顶
Out of memory、
Cannot allocate memory、mysqld 进程被 OOM killer 杀掉 → 内存超限,重点查
innodb_buffer_pool_size、
sort_buffer_size等会为每个连接分配的内存项
Too many open files、
Can't create thread→ 系统级资源瓶颈,比如
/proc/sys/fs/file-max、
ulimit -n、
ulimit -u(最大进程数)设得太低
用命令快速定位真实瓶颈点
别只盯着 MySQL 配置,先跑几条系统命令交叉验证:
查当前 MySQL 打开的文件数:lsof -p $(pgrep mysqld) | wc -l,再对比
cat /proc/$(pgrep mysqld)/limits | grep "Max open files"查内存实际占用:
ps aux --sort=-%mem | head -5看 mysqld 占比;
free -h和
cat /proc/meminfo | grep -i "oom\|commit"看系统是否濒临 OOM 查连接堆积:
mysql -e "SHOW STATUS LIKE 'Threads_connected'; SHOW STATUS LIKE 'Threads_running';",如果
Threads_connected接近
max_connections且长期不降,说明应用没正确复用连接
调整参数前必须检查的三个依赖项
MySQL 参数生效受操作系统硬限制约束,改了也白改:
确保ulimit -n(文件描述符) ≥
max_connections× 1.5(MySQL 内部还需额外句柄) 确保
ulimit -u(最大用户进程数) >
max_connections+ 后台线程数(如
innodb_read_io_threads等) 确保
innodb_buffer_pool_size≤ 物理内存 × 0.7(留足空间给 OS 缓存、其他进程及突发查询临时内存)
容易被忽略的隐性资源消耗点
很多“资源不足”其实来自慢查询或配置失配,而非绝对资源量小:
未加索引的ORDER BY或
GROUP BY会触发
sort_buffer_size全量加载,一个慢查询就吃光几百 MB 内存
tmp_table_size和
max_heap_table_size不一致会导致内存临时表自动转磁盘,大量
Created_tmp_disk_tables指标飙升并拖慢 I/O 应用层长连接空闲不释放,
wait_timeout和
interactive_timeout设得过大(如 28800 秒),连接数缓慢爬升直至打满
真正卡住的往往不是 buffer_pool 大小,而是某个未优化的 JOIN 让 20 个连接同时申请 128MB sort_buffer —— 这时候调大
max_connections只会让 OOM 来得更快。
