轻量级云服务器(1核1G)运行MySQL如何避免内存不足?

在 1 核 1G 的轻量级云服务器上运行 MySQL,内存资源非常紧张。MySQL 默认配置通常是为更高配置的服务器设计的,直接启动极易导致 OOM(Out of Memory)并触发系统杀死 MySQL 进程。

要稳定运行,核心思路是严格限制 MySQL 的内存占用,并优化操作系统层面的内存管理。以下是具体的操作方案:

1. 修改 MySQL 配置文件 (my.cnf)

这是最关键的一步。你需要手动覆盖默认值,将主要内存指标降至安全范围。

请编辑 /etc/my.cnf (CentOS/RHEL) 或 /etc/mysql/my.cnf (Debian/Ubuntu),在 [mysqld] 下添加或修改以下参数:

[mysqld]
# 基础设置
user = mysql
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
port = 3306
datadir = /var/lib/mysql

# --- 核心内存控制参数 ---

# 1. 最大连接数:1G 内存建议设为 50-100,避免每个连接都占用过多 buffer
max_connections = 50

# 2. 关键缓冲池大小 (InnoDB Buffer Pool Size)
# 总内存 1GB,扣除 OS 和 Swap 预留,MySQL 最多只能分约 400MB-500MB
# 建议设置为物理内存的 25%-40%
innodb_buffer_pool_size = 256M

# 3. 日志缓冲区 (Log Buffer) - 减少磁盘 I/O,但占用内存
innodb_log_buffer_size = 8M

# 4. 排序缓冲区 (Sort Buffer) - 每个连接单独分配,必须设小
sort_buffer_size = 64K
read_buffer_size = 64K
read_rnd_buffer_size = 64K

# 5. 线程缓存 (Thread Cache) - 减少创建线程的开销
thread_cache_size = 10

# 6. 查询缓存 (Query Cache)
# 注意:MySQL 5.7+ 已废弃,8.0+ 已移除。如果是旧版本且开启,需设为 0 或极小值
query_cache_type = 0
query_cache_size = 0

# 7. 临时表内存限制
tmp_table_size = 16M
max_heap_table_size = 16M

# 8. 其他调整
table_open_cache = 200
table_definition_cache = 200
open_files_limit = 65535

# --- 可选:如果内存极度紧张,可考虑使用 MyISAM (不推荐生产环境) ---
# 或者强制 InnoDB 仅用于数据文件,不使用额外内存
innodb_flush_log_at_trx_commit = 2
sync_binlog = 0

参数解释与逻辑:

  • innodb_buffer_pool_size: 这是最大的内存消耗项。在 1G 机器上,绝对不能超过 512MB,否则加上 OS 和其他进程必挂。256MB 是一个相对安全的起步值。
  • sort_buffer_size / read_buffer_size: 这些是每连接分配的。如果设为默认的几 MB,50 个连接就会瞬间吃掉几百 MB。必须设为 KB 级别。
  • max_connections: 限制并发量,防止内存被连接队列耗尽。

2. 配置 Linux Swap (虚拟内存)

物理内存只有 1G,必须依赖 Swap 作为“防波堤”。虽然 Swap 会显著降低性能,但在内存溢出时能防止服务崩溃。

  1. 检查是否已有 Swap

    free -h

    如果 Swap 为 0,需要创建。

  2. 创建 Swap 文件(以 1G 为例,建议创建 1G-2G 的 Swap):

    # 创建 1G 的 swap 文件
    sudo fallocate -l 1G /swapfile
    
    # 如果没有 fallocate,可用 dd 命令:sudo dd if=/dev/zero of=/swapfile bs=1M count=1024
    
    # 设置权限
    sudo chmod 600 /swapfile
    
    # 格式化为 swap
    sudo mkswap /swapfile
    
    # 启用
    sudo swapon /swapfile
    
    # 永久生效
    echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
  3. 调整 Swappiness
    让系统在内存充足时尽量少用 Swap,内存紧张时多用。

    # 查看当前值
    cat /proc/sys/vm/swappiness
    
    # 临时调整为 10 (更激进地优先使用物理内存,但保留 Swap 兜底)
    sudo sysctl vm.swappiness=10
    
    # 永久生效
    echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf

    注:对于数据库,Swappiness 设为 10-60 之间比较合适。过低可能导致频繁 OOM Killer 触发,过高会导致性能抖动。

3. 优化应用层与查询习惯

即使配置再完美,低效的 SQL 也会瞬间撑爆内存。

  • 避免全表扫描:确保所有查询字段都有索引。
  • 限制返回行数:严禁使用 SELECT * 不加 LIMIT。例如:SELECT * FROM users LIMIT 100
  • 避免大事务:不要一次性更新或删除成千上万条记录。
  • 监控慢查询:开启慢查询日志,找出执行时间超过 1 秒的 SQL 进行优化。

4. 监控与调试

由于资源敏感,必须实时监控。

  • 安装监控工具

    # CentOS
    yum install -y htop sysstat
    
    # Ubuntu/Debian
    apt install -y htop
  • 观察指标
    • 使用 htop 观察 RES (常驻内存) 是否接近 900MB+。
    • 关注 OOM Killer 日志:dmesg | grep -i "killed process"。如果出现此日志,说明内存确实不够,需要进一步调小 innodb_buffer_pool_size 或增加 Swap。

总结建议

在 1 核 1G 环境下:

  1. 首要任务:将 innodb_buffer_pool_size 锁定在 256M 左右。
  2. 次要任务:设置 1G Swap 并调整 swappiness
  3. 长期方案:如果业务增长,1G 内存仅适合测试、开发环境或极低流量的个人博客。生产环境建议至少升级到 2G 内存,此时可以将 innodb_buffer_pool_size 提升至 1G 左右,性能会有质的飞跃。
未经允许不得转载:CLOUD技术博 » 轻量级云服务器(1核1G)运行MySQL如何避免内存不足?