针对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
六、配置检查清单
- ✅
innodb_buffer_pool_size≤ 512MB - ✅ 所有连接级缓冲区(*_buffer_size)总和 × max_connections < 500MB
- ✅
vm.swappiness≤ 10 - ✅ Swap空间 ≥ 1GB
- ✅
max_connections≤ 50 - ✅ 监控报警设置(swap使用 > 50%时告警)
最终建议:
对于2GB内存的虚拟机,MySQL内存上限应控制在1-1.2GB,为系统和其他进程保留800MB以上空间。使用轻量级监控如 netdata 或自定义脚本监控swap使用。如果数据量持续增长,建议升级内存或考虑使用SQLite/PostgreSQL(内存管理更友好)替代。
CLOUD技术笔记