速卖通素材
奋斗

1核1G云服务器部署MySQL后经常OOM,如何优化内存使用?

服务器

在 1 核 1G 的云服务器上部署 MySQL,内存资源非常紧张,默认配置极易触发 OOM(Out Of Memory)。以下是针对该环境的优化方案,按优先级排序:


✅ 核心原则:限制 MySQL 最大内存占用

MySQL 默认会尝试使用大量内存(如 innodb_buffer_pool_size 默认为物理内存的 50%~75%),在 1G 机器上直接导致 OOM。


🔧 关键优化步骤

1. 调整 my.cnf / mysql.cnf 配置文件

编辑 /etc/my.cnf/etc/mysql/my.cnf,在 [mysqld] 段添加/修改以下参数:

[mysqld]
# 基础设置
max_connections = 20          # 降低并发连接数(默认 151)
thread_cache_size = 4         # 减少线程缓存开销

# InnoDB 缓冲池(最关键!)
innodb_buffer_pool_size = 256M   # 建议设为 25%~30% 物理内存(1G → 256M~300M)
innodb_log_file_size = 64M       # 日志文件大小(默认可能过大)
innodb_flush_method = O_DIRECT   # 避免双重缓冲,减少内存压力

# 其他内存相关
tmp_table_size = 16M             # 临时表最大内存大小
max_heap_table_size = 16M        # 同上
sort_buffer_size = 1M            # 排序缓冲区(默认 2M+,可降)
read_buffer_size = 1M            # 顺序读缓冲区
read_rnd_buffer_size = 512K      # 随机读缓冲区
join_buffer_size = 1M            # JOIN 缓冲区(默认 4M+)

# 关闭不必要功能
skip-name-resolve                # 禁用 DNS 反向解析(提升启动速度 & 减少网络请求)
log_queries_not_using_indexes = OFF  # 仅记录慢查询(可选)

# 安全限制
performance_schema = OFF         # 性能监控消耗内存,生产小机可关闭

💡 注意:所有 *_buffer_size 类参数是每个连接独占的,务必调低;而 innodb_buffer_pool_size 是全局共享的,可相对保留更多。


2. 启用 Swap(虚拟内存)

即使有 Swap,MySQL 仍可能因 oom_score_adj 被杀,但能争取时间并防止系统崩溃:

# 创建 512M~1G swap 文件
sudo fallocate -l 512M /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

# 永久生效
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

# 调整内核参数:允许 MySQL 使用 Swap(谨慎)
sudo sysctl vm.swappiness=10   # 值越小越倾向用物理内存(推荐 1~10)

⚠️ 若仍频繁 OOM,可尝试提高 MySQL 进程 OOM 优先级(使其更难被杀):

# 查看当前 PID
ps aux | grep mysql
# 假设 PID 为 1234
echo -1000 | sudo tee /proc/1234/oom_score_adj
# 或写入 systemd 服务(若用 systemd)

3. 监控与诊断

  • 实时内存监控:
    free -h
    top -o %MEM
  • MySQL 内部内存统计:
    SHOW STATUS LIKE 'Innodb_buffer_pool%';
    SHOW VARIABLES LIKE '%buffer%';
    SHOW PROCESSLIST;  -- 查是否有大查询/长事务
  • 慢查询日志开启(避免全表扫描拖垮内存):
    slow_query_log = 1
    slow_query_log_file = /var/log/mysql/slow.log
    long_query_time = 2
    log_queries_not_using_indexes = 1

4. 应用层优化(同等重要)

  • 避免 SELECT *,只查必要字段;
  • 加索引覆盖常用查询;
  • 控制单次查询返回行数(LIMIT);
  • 使用连接池(如 HikariCP),避免短连接频繁创建销毁;
  • 定期清理大表、归档历史数据。

📊 参考配置示例(1C1G 实测可用)

[mysqld]
user=mysql
pid-file=/var/run/mysqld/mysqld.pid
socket=/var/run/mysqld/mysqld.sock
port=3306
basedir=/usr
datadir=/var/lib/mysql
tmpdir=/tmp
skip-name-resolve
max_connections=20
innodb_buffer_pool_size=256M
innodb_log_file_size=64M
innodb_flush_method=O_DIRECT
tmp_table_size=16M
max_heap_table_size=16M
sort_buffer_size=1M
read_buffer_size=1M
read_rnd_buffer_size=512K
join_buffer_size=1M
performance_schema=OFF
thread_cache_size=4

重启后验证:

systemctl restart mysqld
free -h
mysql -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"

⚠️ 最后建议

如果业务负载较重(如高频写入、复杂 JOIN、大结果集),1C1G 已接近 MySQL 运行底线。长期方案应考虑:

  • 升级到 2C2G(成本增加有限,稳定性显著提升);
  • 或改用轻量级数据库(如 SQLite + 读写分离、Redis 做缓存层减轻 DB 压力);
  • 或使用云厂商的 Serverless MySQL(按需计费,自动扩缩容)。

需要我帮你生成完整的 my.cnf 文件或分析具体慢查询吗?

未经允许不得转载:轻量云Cloud » 1核1G云服务器部署MySQL后经常OOM,如何优化内存使用?