2核2GB的CentOS/Ubuntu虚拟机安装MySQL后,如何优化内存使用避免swap频繁?

针对2核2GB内存的虚拟机安装MySQL,优化内存使用避免swap频繁的关键在于严格控制MySQL内存分配,并调整系统参数。以下是具体优化步骤:


一、MySQL配置优化(核心)

编辑 /etc/my.cnf/etc/mysql/my.cnf,在 [mysqld] 部分添加:

# 基础设置
innodb_buffer_pool_size = 256M   # 关键!设置为物理内存的15-25%(2GB内存建议256-512M)
key_buffer_size = 32M            # MyISAM表索引缓存(如无MyISAM表可设更小)
query_cache_size = 0             # MySQL 8.0已移除,5.7建议关闭或设小
query_cache_type = 0

# 连接相关
max_connections = 50             # 减少并发连接数(默认151过大)
thread_cache_size = 4
table_open_cache = 200

# InnoDB优化
innodb_log_file_size = 64M
innodb_flush_log_at_trx_commit = 2  # 平衡性能与数据安全
innodb_flush_method = O_DIRECT
innodb_file_per_table = ON

# 临时表
tmp_table_size = 32M
max_heap_table_size = 32M

# 其他内存控制
sort_buffer_size = 256K          # 每个连接独享,勿设大!
join_buffer_size = 128K
read_buffer_size = 128K
read_rnd_buffer_size = 256K

关键原则

  • 所有连接独享的内存参数(如 sort_buffer_size)必须设小,因为每个连接都会分配。
  • innodb_buffer_pool_size 是最大内存占用项,务必控制在 500MB 以内。

二、操作系统优化

1. 调整Swappiness

# 临时生效
sudo sysctl vm.swappiness=10

# 永久生效
echo "vm.swappiness=10" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

(建议值5-10,降低swap使用倾向)

2. 调整缓存压力

echo "vm.vfs_cache_pressure=50" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

3. 添加Swap空间(预防性)

如果未配置swap或swap太小(<1GB):

# 创建2GB交换文件
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

三、MySQL内存使用监控

1. 计算当前内存配置上限

-- 运行以下SQL查看单个连接最大内存
SELECT @@innodb_buffer_pool_size 
     + @@key_buffer_size 
     + @@max_connections * (@@sort_buffer_size 
                          + @@read_buffer_size 
                          + @@read_rnd_buffer_size 
                          + @@join_buffer_size 
                          + @@thread_stack) / 1024 / 1024 AS "Max MB";

2. 监控工具

# 实时查看内存和swap
watch -n 1 "free -m"

# 查看MySQL内存分配
ps aux | grep mysqld | grep -v grep
pmap -x $(pgrep mysqld) | tail -1

# 查看swap使用进程
sudo swapon --show
sudo smem -s swap

四、服务限制与维护

1. 限制MySQL内存

# 使用systemd限制(CentOS 7+/Ubuntu 16.04+)
sudo systemctl edit mysqld

# 添加:
[Service]
MemoryLimit=1.5G

2. 定期清理

-- 清理旧连接
SET GLOBAL max_connections = 50;
KILL PROCESSLIST_ID; -- 按需结束空闲连接

-- 优化表
OPTIMIZE TABLE 重要表名;

五、应急处理

如果已出现swap频繁:

# 1. 立即清理缓存
sync; echo 3 | sudo tee /proc/sys/vm/drop_caches

# 2. 临时重启MySQL释放内存
sudo systemctl restart mysqld

# 3. 禁用swap(临时)
sudo swapoff -a && sudo swapon -a

六、配置检查清单

  1. innodb_buffer_pool_size ≤ 512MB
  2. ✅ 所有连接级缓冲区(*_buffer_size)总和 × max_connections < 500MB
  3. vm.swappiness ≤ 10
  4. ✅ Swap空间 ≥ 1GB
  5. max_connections ≤ 50
  6. ✅ 监控报警设置(swap使用 > 50%时告警)

最终建议
对于2GB内存的虚拟机,MySQL内存上限应控制在1-1.2GB,为系统和其他进程保留800MB以上空间。使用轻量级监控如 netdata 或自定义脚本监控swap使用。如果数据量持续增长,建议升级内存或考虑使用SQLite/PostgreSQL(内存管理更友好)替代。

云服务器