在 2 核 1GB 内存的 Linux 服务器上部署 MySQL,核心挑战是内存极度受限。默认配置(如 innodb_buffer_pool_size)通常会占用过多内存导致 OOM(Out of Memory)崩溃。必须对关键参数进行激进调整,并配合系统级优化。
以下是必须调整的关键参数及配置建议:
1. MySQL 核心内存参数 (my.cnf / mysql.cnf)
这是最关键的步骤,目标是让 MySQL 占用的总内存不超过物理内存的 60%~70%(预留约 300MB 给操作系统和其他进程)。
| 参数名 | 推荐值 (2C1G) | 说明与调整理由 |
|---|---|---|
innodb_buffer_pool_size |
256M (或 192M) | 最重要参数。InnoDB 缓冲池用于缓存数据和索引。默认通常是物理内存的 50%(即 512M),这会导致系统内存不足。建议设置为 256M 或更小,确保不触发 Swap。 |
max_connections |
50 | 限制最大连接数。每个连接都会消耗内存(约 2-4MB),高并发下极易撑爆内存。对于小服务器,50 已足够,甚至可设为 30。 |
thread_cache_size |
10 | 减少线程创建/销毁的开销,同时控制内存占用。 |
query_cache_size |
0 | 强烈建议关闭。Query Cache 在 MySQL 8.0 中已被移除,且在低内存环境下维护成本极高,容易引发碎片和锁竞争。如果使用的是 MySQL 5.7,也建议设为 0。 |
tmp_table_size |
16M | 临时表大小限制。防止大查询在内存中生成过大的临时表后转磁盘失败。 |
max_heap_table_size |
16M | 同上,与 tmp_table_size 保持一致。 |
join_buffer_size |
1M | 连接缓冲区默认可能较大(如 4M),需调小以防止单条复杂 JOIN 操作耗尽内存。 |
sort_buffer_size |
1M | 排序缓冲区,默认可能过大,需严格限制。 |
read_buffer_size |
1M | 顺序读缓冲区,同样需要限制。 |
table_open_cache |
400 | 打开文件描述符的数量限制,根据实际表数量适当调整,避免过高。 |
配置文件示例 (/etc/my.cnf 片段):
[mysqld]
# 基础设置
basedir = /usr
datadir = /var/lib/mysql
port = 3306
socket = /var/lib/mysql/mysql.sock
# 内存优化 (核心)
innodb_buffer_pool_size = 256M
max_connections = 50
thread_cache_size = 10
# 关闭查询缓存 (MySQL 5.7+)
query_cache_size = 0
query_cache_type = 0
# 限制其他缓冲区,防止单个查询吃光内存
tmp_table_size = 16M
max_heap_table_size = 16M
join_buffer_size = 1M
sort_buffer_size = 1M
read_buffer_size = 1M
# 日志与性能
log_error = /var/log/mysqld.log
slow_query_log = 1
long_query_time = 2
slow_query_log_file = /var/log/mysql-slow.log
2. 操作系统级优化
除了 MySQL 内部参数,Linux 内核参数也需要微调以应对低内存环境。
A. 禁用或最小化 Swap (虚拟内存)
在 1GB 内存下,一旦使用 Swap,数据库性能会急剧下降(I/O 瓶颈),且可能导致服务假死。
- 检查 Swap:
free -h - 临时关闭:
swapoff -a - 永久关闭: 编辑
/etc/fstab,注释掉 swap 行,然后执行swapoff -a。- 注意: 如果业务负载偶尔突增,完全关闭 Swap 可能导致 OOM Killer 直接杀掉 MySQL 进程。如果担心稳定性,可以保留少量 Swap(如 256MB),但需设置
vm.swappiness。
- 注意: 如果业务负载偶尔突增,完全关闭 Swap 可能导致 OOM Killer 直接杀掉 MySQL 进程。如果担心稳定性,可以保留少量 Swap(如 256MB),但需设置
B. 调整 Swappiness
如果决定保留少量 Swap,需要降低内核使用 Swap 的倾向性。
- 命令:
sysctl vm.swappiness=10 - 永久生效: 在
/etc/sysctl.conf中添加vm.swappiness=10。- 解释:值为 0-100,越小越倾向于使用物理内存。10 表示仅在物理内存几乎用尽时才使用 Swap。
C. 调整文件描述符限制
MySQL 在高连接数下需要大量文件句柄。
- 命令:
ulimit -n 65535 - 永久生效: 编辑
/etc/security/limits.conf,添加:mysql soft nofile 65535 mysql hard nofile 65535
3. 启动验证与监控
修改配置后,务必验证内存占用情况:
- 重启 MySQL:
systemctl restart mysqld(或service mysql restart)。 - 查看实际内存:
- 使用
top命令观察RES(常驻内存) 列。 - 在 MySQL 内部执行:
SHOW VARIABLES LIKE 'innodb_buffer_pool_size'; SHOW STATUS LIKE 'Threads_connected'; SHOW GLOBAL STATUS LIKE 'Bytes_used'; -- 估算当前内存使用情况
- 使用
- 监控 OOM: 检查系统日志
/var/log/messages或dmesg | grep -i kill,确认是否有 OOM Killer 杀死了 MySQL 进程。
总结建议
在 2 核 1GB 的配置下,“稳”比“快”更重要。
- 首要任务:将
innodb_buffer_pool_size强制降至 256M 以下。 - 次要任务:大幅调小各类 Buffer (
join,sort,read) 至 1M 级别。 - 架构建议:如果应用流量稍大,考虑开启 慢查询日志 并及时优化 SQL;或者考虑使用 SQLite 替代(如果是简单应用),或者升级到更高配置的云主机(2 核 1G 运行生产级 MySQL 非常吃力)。
云知道CLOUD