在仅 2GB 内存 的 CentOS 或 Ubuntu 服务器上安装 MySQL(推荐使用 MySQL 8.0+ 或 MariaDB 10.6+,避免已停止维护的旧版),必须进行严格内存优化,否则极易因 OOM(Out of Memory)被系统 kill,或导致严重性能抖动。以下是关键调整建议(以 MySQL 8.0 为主,兼容 MariaDB,附注差异):
✅ 一、核心原则(必读)
- 总内存占用 ≤ 1.2–1.4 GB(预留 600–800MB 给 OS、SSH、基础服务等)
- 禁用非必要功能(如 Performance Schema、InnoDB 缓冲池过大、Query Cache 等)
- 使用
innodb_buffer_pool_size作为最大内存消耗项,绝对不可超过 1GB - 避免启用
innodb_file_per_table=OFF(默认 ON,保持即可)
✅ 二、推荐 my.cnf(/etc/mysql/my.cnf 或 /etc/my.cnf)关键配置
[mysqld]
# === 基础设置 ===
skip-name-resolve # 提速连接,禁用 DNS 反查
default-storage-engine = InnoDB
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
# === 内存相关(最关键!)===
# ✅ 必须设为物理内存的 40%~50%,2GB → 推荐 800M~1000M(保守选 896M)
innodb_buffer_pool_size = 896M
# 减少缓冲池实例数(避免碎片和开销),2GB机器设为1
innodb_buffer_pool_instances = 1
# 日志缓冲区(小内存下无需大值)
innodb_log_buffer_size = 2M
# 重做日志总大小(建议 64M~128M,兼顾崩溃恢复与写入性能)
innodb_log_file_size = 64M
innodb_log_files_in_group = 2 # 总重做日志空间 = 2 × 64M = 128M
# === 连接与查询 ===
# 最大连接数:2GB机器不宜过高(每个连接至少占用几MB内存)
max_connections = 50 # 默认151,过高易OOM;按实际需求调(如Web应用通常30–50够用)
wait_timeout = 300 # 空闲连接超时(秒),及时释放
interactive_timeout = 300
# 查询缓存:❌ MySQL 8.0+ 已移除;MariaDB 10.6+ 默认禁用,无需配置
# query_cache_type = 0 # (仅MariaDB < 10.6需显式关闭)
# === 临时表与排序 ===
tmp_table_size = 32M
max_heap_table_size = 32M # 二者必须相等,防隐式转换到磁盘临时表
sort_buffer_size = 256K # 每连接分配,勿设过大(默认256K合理)
read_buffer_size = 128K
read_rnd_buffer_size = 256K
join_buffer_size = 256K
# ❌ 禁止设 > 1M!否则50连接即吃掉 50×1M = 50MB+ 内存
# === 日志与监控(降低开销)===
slow_query_log = OFF # 生产环境可开,但建议先关;如需,设 slow_query_log_file + long_query_time=2
log_error = /var/log/mysql/error.log
# ❌ 关闭 Performance Schema(内存大户,2GB机器强烈建议关闭)
performance_schema = OFF
# === 其他安全/稳定项 ===
innodb_flush_log_at_trx_commit = 1 # 数据安全性优先(默认,勿改!若允许丢1s数据可设2,但不推荐)
sync_binlog = 1 # 同上,保障主从/崩溃安全(若不用复制可设0,但风险高)
# 可选:禁用表扫描警告(减少日志)
log_queries_not_using_indexes = OFF
# === MariaDB 特有补充(如使用)===
# [mysqld]
# skip-innodb # ❌ 绝对不要禁InnoDB!MyISAM不支持事务且并发差
# default-storage-engine = InnoDB
🔔 重要提示:
- 修改
innodb_log_file_size后,必须先停止 MySQL,删除旧日志文件(如ib_logfile0,ib_logfile1),再启动(MySQL 8.0+ 支持在线调整,但2GB机器建议停机操作更稳妥)。- 所有
*_size参数单位:K(千字节)、M(兆字节)、G(吉字节),如896M。
✅ 三、系统级配合优化(CentOS/Ubuntu 通用)
| 项目 | 操作 | 原因 |
|---|---|---|
| Swap 分区 | ✅ 确保有 1–2GB swap(即使 SSD) | 防止 OOM Killer 杀 MySQL;设 vm.swappiness=1(sysctl -w vm.swappiness=1)降低交换倾向 |
| OOM Score 调整 | echo -1000 > /proc/$(pidof mysqld)/oom_score_adj(开机加到 /etc/rc.local 或 systemd service) |
降低 MySQL 被 OOM Killer 选中的概率 |
| 限制 MySQL 内存(可选) | 在 systemd 中(/etc/systemd/system/mysqld.service.d/override.conf)添加:[Service]MemoryLimit=1.3G |
更硬性保障(需 systemd ≥229) |
✅ 四、安装后验证与监控
# 1. 检查实际内存使用(重点关注 buffer pool)
mysql -u root -p -e "SHOW ENGINE INNODB STATUSG" | grep "Buffer pool size"
# 2. 查看当前连接与内存估算
mysql -u root -p -e "SHOW STATUS LIKE 'Threads_connected'; SHOW VARIABLES LIKE 'max_connections';"
# 3. 监控进程内存(RSS)
ps -o pid,user,vsz,rss,comm -C mysqld
# 4. 检查错误日志是否有 OOM 或内存告警
tail -20 /var/log/mysql/error.log
✅ 健康指标参考:
mysqldRSS(常驻内存)应稳定在 900–1100 MB(含 buffer pool + 连接开销)Threads_connected长期 ≤ 30- 无
Out of memory: Kill process mysqld系统日志
✅ 五、替代建议(更轻量场景)
如果只是开发/测试/极低流量(<10 QPS),考虑:
- ✅ MariaDB 替代 MySQL:同等配置下内存略低,且
aria引擎更省资源(但需业务兼容) - ✅ SQLite:单机、无并发写场景(如后台工具、嵌入式)
- ✅ Docker 轻量镜像:
mysql:8.0-oracle官方镜像 + 上述配置,便于隔离
❌ 绝对禁止的操作
innodb_buffer_pool_size > 1024Mmax_connections > 100- 开启
performance_schema或innodb_monitor_enable - 使用
query_cache(MySQL 8.0+ 不存在,MariaDB 10.6+ 默认禁用) innodb_flush_method = O_DIRECT(小内存+机械盘可能反效果,保持默认fsync即可)
如需我帮你生成完整 my.cnf 文件(适配你的具体版本/发行版)、编写 systemd 内存限制脚本、或分析 SHOW STATUS 输出,请随时提供:
cat /etc/os-releasemysql --version或mariadb --version- 当前
my.cnf内容(脱敏)
我可以为你定制化优化 👇
CDNK博客