温馨提示×

ubuntu mysql为何占用高内存

小樊
48
2026-09-10 01:40:11
栏目: 云计算

在 Ubuntu 上 MySQL 占用内存高,通常不是“内存泄漏”,而是 MySQL 本身设计就是吃内存的,再加上配置或业务因素。下面按常见原因 → 排查方法 → 解决建议说明。


一、MySQL 内存都去哪了(核心原因)

MySQL 内存主要分为几块:

  1. 全局缓冲(最重要)
    • innodb_buffer_pool_size(默认可能很大)
    • 查询缓存(MySQL 8 已移除)
  2. 连接级内存
    • 每个连接都会占用内存
    • sort_buffer_size
    • join_buffer_size
    • read_buffer_size
  3. 临时表
    • 内存临时表
    • 磁盘临时表
  4. 业务问题
    • 慢查询
    • 全表扫描
    • 大量连接

二、最常见原因(90% 的情况)

1️⃣ innodb_buffer_pool_size 设置过大(最常见)

现象

  • 刚启动 MySQL 内存不高
  • 运行一段时间后内存稳定在高水位

查看

SHOW VARIABLES LIKE 'innodb_buffer_pool_size';

解释

  • InnoDB 会把数据和索引缓存在内存
  • 这是“正常占用”,不是泄漏

建议

  • 专用数据库服务器:内存的 60–70%
  • 混合服务器(Web+DB):30–50%

修改:

# /etc/mysql/mysql.conf.d/mysqld.cnf
innodb_buffer_pool_size = 1G

2️⃣ 连接数太多(每个连接都吃内存)

查看最大连接

SHOW VARIABLES LIKE 'max_connections';
SHOW STATUS LIKE 'Threads_connected';

问题

  • 每个连接 ≈ 几 MB
  • 1000 连接可能占用 2–4GB

解决

  • 限制连接数
  • 使用连接池(如 PHP/Java 连接池)
  • 杀掉空闲连接

3️⃣ 排序 / JOIN 缓冲设置过大

常见于:

sort_buffer_size = 4M
join_buffer_size = 4M

如果 500 连接 × 4M = 2GB

✅ 推荐:

sort_buffer_size = 256K
join_buffer_size = 256K

4️⃣ 慢查询导致临时表暴涨

查看

SHOW STATUS LIKE 'Created_tmp%';

如果:

  • Created_tmp_disk_tables 很高 说明:
  • 查询没走索引
  • 在用磁盘临时表

✅ 解决:

  • 加索引
  • 避免 SELECT *
  • 减少 GROUP BY / ORDER BY 大表

5️⃣ Ubuntu + systemd 看起来“内存高”

Linux 会把 空闲内存当缓存

free -h

available,不是 free

✅ MySQL 占用高但系统不卡 = 正常


三、快速排查清单(实用)

# MySQL 进程内存
ps aux | grep mysqld

# 当前连接
mysql -e "SHOW PROCESSLIST;"

# 缓冲池大小
mysql -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"

四、推荐的“安全配置示例”(小内存服务器)

[mysqld]
innodb_buffer_pool_size = 512M
max_connections = 100
sort_buffer_size = 256K
join_buffer_size = 256K
tmp_table_size = 64M
max_heap_table_size = 64M

五、一句话总结

Ubuntu 上 MySQL 内存高,90% 是因为 innodb_buffer_pool_size 大或连接多,这是设计行为,不是故障。

如果你愿意,可以把:

  • free -h
  • SHOW VARIABLES LIKE '%buffer%';
  • SHOW STATUS LIKE 'Threads%';

贴出来,我可以帮你 精确算内存占用是否合理

0