在仅 2GB 内存 的 CentOS 或 Ubuntu 服务器上安装 MySQL(推荐使用 MySQL 8.0+ 或 MariaDB,但需极度精简配置),必须严格限制内存占用,避免因 OOM(Out of Memory)被系统 kill。以下是关键调整建议(以 MySQL 8.0 为主,兼容性说明见后):
✅ 一、核心原则
- 总内存预留:系统 + MySQL + 其他服务(如 SSH、日志等)共用 2GB → MySQL 建议最大内存占用 ≤ 800–1000 MB
- 禁用非必要功能:InnoDB 缓冲池以外的缓存尽量最小化,关闭性能模式、查询缓存(已废弃)、复制相关(除非必需)。
- 使用 SSD(强烈建议):机械盘下
innodb_flush_method=O_DIRECT可能导致性能恶化,需测试。
✅ 二、关键配置项(/etc/my.cnf 或 /etc/mysql/my.cnf)
[mysqld]
# === 基础设置 ===
port = 3306
bind-address = 127.0.0.1 # 仅本地访问,提升安全与性能
skip-networking = OFF # 若需远程访问,改为 ON 并配防火墙;否则保持 OFF
max_connections = 50 # 默认151,2GB下50足够(每个连接约2–5MB内存)
table_open_cache = 64 # 原默认 4000 → 大幅降低打开表缓存
tmp_table_size = 32M
max_heap_table_size = 32M
sort_buffer_size = 256K # 每连接排序缓冲,勿超 512K
read_buffer_size = 128K
read_rnd_buffer_size = 256K
join_buffer_size = 256K
# 注意:以上 per-connection 参数 × max_connections ≈ 预估连接内存开销
# === InnoDB(最关键!占内存大头)===
innodb_buffer_pool_size = 512M # ⚠️ 核心参数!建议 512–768M(不超过物理内存 40%)
innodb_buffer_pool_instances = 1 # <1GB时设为1,避免碎片
innodb_log_file_size = 64M # 默认 48M → 64M 平衡恢复速度与磁盘空间(需先停库重命名旧日志)
innodb_log_buffer_size = 2M # 默认1M,够用
innodb_flush_log_at_trx_commit = 1 # 安全优先(=2 会提升性能但有1s数据丢失风险)
innodb_flush_method = O_DIRECT # Linux 下推荐(绕过OS cache,避免双缓存);若IO异常可试 `fsync`
innodb_io_capacity = 200 # 机械盘用100–200,SSD可用500–1000
innodb_io_capacity_max = 400
# === 禁用/降低开销功能 ===
performance_schema = OFF # ⚠️ 必关!默认ON且吃内存(2GB下可占200MB+)
innodb_stats_on_metadata = OFF # 防止 SHOW TABLES 等操作触发统计更新
skip_log_bin = ON # 关闭binlog(除非需要主从或PITR)
log_error = /var/log/mysql/error.log
slow_query_log = OFF # 如需调试再临时开启
long_query_time = 2
# === 其他安全/兼容 ===
sql_mode = STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
🔍 验证 innodb_buffer_pool_size 合理性:
512M + (50×(256K+128K+256K+256K)) ≈ 512M + 50×896K ≈ 512M + 45M ≈ 557M
再加上系统保留、线程栈等,总 MySQL 内存可控在 ~700–900MB。
✅ 三、安装后必做优化步骤
-
初始化并启动前清理旧日志(如调整
innodb_log_file_size):sudo systemctl stop mysql sudo mv /var/lib/mysql/ib_logfile* /tmp/ # 备份后删除 sudo systemctl start mysql -
检查实际内存使用:
# 查看 MySQL 进程RSS(常驻内存) ps -o pid,user,%mem,rss,comm -C mysqld # 查看 InnoDB 缓冲池使用率(登录MySQL后) mysql -u root -p -e "SHOW ENGINE INNODB STATUSG" | grep "Buffer pool hit rate" # 理想 > 990/1000(即99%+) -
禁用 swap(可选但推荐):
MySQL 在 swap 上性能极差,2GB小内存建议关闭 swap(或设vm.swappiness=1):echo 'vm.swappiness=1' | sudo tee -a /etc/sysctl.conf && sudo sysctl -p -
启用 systemd 内存限制(增强防护):
编辑/etc/systemd/system/mysqld.service.d/limit.conf:[Service] MemoryLimit=900M然后重载:
sudo systemctl daemon-reload && sudo systemctl restart mysql
✅ 四、CentOS vs Ubuntu 差异提示
| 项目 | CentOS 7/8 | Ubuntu 20.04/22.04 |
|---|---|---|
| 配置文件路径 | /etc/my.cnf 或 /etc/my.cnf.d/server.cnf |
/etc/mysql/my.cnf(主)+ /etc/mysql/mysql.conf.d/mysqld.cnf |
| 包管理器 | yum / dnf |
apt |
| 默认 MySQL | CentOS 7: MariaDB 5.5;CentOS 8+: MySQL 8.0 或 MariaDB 10.3+ | Ubuntu 20.04+: MySQL 8.0(官方源) |
| SELinux | CentOS 默认启用 → 若报错加 setsebool -P mysqld_disable_transitive 1 或临时 setenforce 0 测试 |
Ubuntu 无 SELinux(用 AppArmor,一般不影响) |
💡 Ubuntu 用户注意:若用
mysql-server包,配置可能被拆分,优先修改/etc/mysql/mysql.conf.d/mysqld.cnf
✅ 五、替代建议(更轻量、更稳妥)
- ✅ 考虑 MariaDB 10.6+:对小内存更友好,
aria引擎比 MyISAM 更可靠,且innodb_buffer_pool_size行为更稳定; - ✅ 生产环境强烈建议升级到 ≥ 4GB 内存:2GB 仅适合开发/测试/极低流量(<10 QPS)场景;
- ✅ 应用层优化:开启连接池(如 HikariCP)、避免
SELECT *、合理建索引、定期OPTIMIZE TABLE(对小表)。
✅ 六、快速验证脚本(部署后运行)
# 检查关键参数是否生效
mysql -u root -p -Nse "
SELECT
@@innodb_buffer_pool_size/1024/1024 AS 'buffer_pool_mb',
@@max_connections AS 'max_connections',
@@performance_schema AS 'perf_schema',
@@skip_log_bin AS 'binlog_disabled'
"
# 检查内存警告(OOM Killer 是否杀过 mysqld)
dmesg -T | grep -i "killed process" | grep mysqld
如有具体场景(如 WordPress、Discourse、自研应用),可进一步定制(例如 WordPress 可调 query_cache_type=0 虽已废弃,但确保不残留)。欢迎补充细节,我可帮你生成完整配置文件 👇
需要我为你生成一个 开箱即用的 my.cnf 完整模板(适配 Ubuntu 22.04 + MySQL 8.0) 吗?
云服务器