在 1 核 1G(1GB)内存的轻量级服务器上运行 MySQL,必须严格限制 MySQL 的内存占用,否则极易触发 Linux OOM Killer 导致数据库崩溃。以下是经过验证的优化方案:
✅ 核心原则:只给 MySQL 分配 ≤ 400MB 内存
剩余内存留给操作系统、Swap 和其他进程(如 Web 服务)。建议配置如下:
1. 修改 my.cnf / mysql.cnf 配置文件
[mysqld]
# 基础设置
basedir = /usr
datadir = /var/lib/mysql
port = 3306
socket = /tmp/mysql.sock
skip-name-resolve # 禁用 DNS 解析,减少开销和延迟
# ⚠️ 关键:限制内存参数(按 1G 总内存估算)
innodb_buffer_pool_size = 128M # 默认可能高达 75%+,必须大幅降低
key_buffer_size = 16M # MyISAM 索引缓存(若只用 InnoDB 可设 0)
max_allowed_packet = 4M # 避免大查询/大包占用
thread_stack = 192K # 线程栈大小
table_open_cache = 64 # 表打开缓存
sort_buffer_size = 128K # 排序缓冲区(单连接)
read_buffer_size = 128K # 顺序读缓冲区
read_rnd_buffer_size = 128K # 随机读缓冲区
join_buffer_size = 128K # 连接缓冲区
# 安全与稳定性
max_connections = 20 # 限制并发连接数(避免内存爆炸)
wait_timeout = 300 # 空闲超时缩短
interactive_timeout = 300
# 日志(可选:生产环境建议开启慢查询日志用于调优)
slow_query_log = 1
long_query_time = 2
log_output = FILE
📌 注意:
innodb_buffer_pool_size是最大风险项!1G 机器设为 128M~256M 即可;- 所有
*_buffer_size参数都是每个连接独立分配,因此必须设小 + 限制max_connections;- 使用
systemd或supervisor管理时,确保未额外设置LimitMEMLOCK等限制冲突。
✅ 2. 启用并合理配置 Swap
即使有 Swap,MySQL 也不会主动使用它(除非配置了 swap_priority 等),但它是防止 OOM 的最后一道防线:
# 创建 1G Swap 文件(根据磁盘空间调整)
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# 永久生效:写入 /etc/fstab
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
# 调整 Swappiness(推荐值 10~60,避免过早用 Swap)
sudo sysctl vm.swappiness=10
# 临时生效:
# sudo sysctl vm.swappiness=10
💡 提示:Swappiness=10 表示系统尽量不用 Swap,仅在物理内存紧张时才使用,适合 DB 场景。
✅ 3. 监控与诊断工具
- 实时查看内存占用:
free -h top -o %MEM # 观察 mysql 进程 RSS ps aux --sort=-%mem | head -n 10 - 检查是否被 OOM Kill:
dmesg | grep -i "out of memory" journalctl -xe | grep -i "killed process" - 启动后验证配置:
SHOW VARIABLES LIKE '%buffer%'; SHOW STATUS LIKE 'Threads_connected';
✅ 4. 应用层优化建议
- 避免全表扫描:为常用查询字段加索引;
- 禁止
SELECT *,只查必要列; - 控制单次查询返回行数(
LIMIT); - 使用连接池(如 HikariCP),避免频繁建连;
- 定期清理慢查询日志中的低效 SQL。
❌ 常见错误配置(务必避免)
| 错误做法 | 后果 |
|---|---|
保留默认 innodb_buffer_pool_size = 75% RAM |
直接 OOM |
max_connections = 100+ |
每个连接消耗几十 KB~几 MB → 瞬间耗尽 |
未禁用 skip-name-resolve |
DNS 反向解析卡顿 + 额外线程资源 |
| 关闭 Swap 且无内存预警机制 | 突发流量下立即崩溃 |
🔁 替代方案(如业务允许)
如果上述仍不稳定,考虑:
- 改用 SQLite(单机文件型,无守护进程,内存极省);
- 迁移到 云厂商托管 RDS 入门版(通常 512MB~1GB 起步,含自动调优);
- 使用 Percona Server for MySQL 或 MariaDB(部分版本对低配更友好);
- 将数据读写分离:MySQL 只做主库,从库放 Redis 缓存热点数据。
需要我帮你生成一份完整的 /etc/my.cnf 模板(适配 Debian/Ubuntu/CentOS)或提供一键部署脚本吗?
CLOUD云枢