在 1 核 2G 的 Linux 服务器上部署 MySQL 8,资源非常紧张。MySQL 默认配置通常是为多核大内存设计的,直接运行会导致频繁的 Swap 交换(Swap Thrashing),进而引发数据库卡顿甚至崩溃。
以下是针对该硬件环境的核心优化策略和具体参数建议:
核心原则
- 严格控制内存占用:确保 MySQL 使用的内存不超过物理内存的 60%-70%(即约 1.2GB – 1.4GB),预留足够空间给操作系统和其他进程。
- 禁用或减少 Swap 使用:尽量让系统不产生 Swap,如果必须产生,需确保 MySQL 不会频繁触发 Swap。
- 单核优化:由于只有 1 个 CPU 核心,多线程并发能力受限,需限制连接数和线程池大小,避免上下文切换开销过大。
关键参数配置 (my.cnf / mysql.cnf)
请在 /etc/my.cnf 的 [mysqld] 部分添加或修改以下参数:
1. 内存管理 (最关键)
[mysqld]
# 设置最大可用内存为总内存的 50%~60%,防止 OOM
# 2G * 0.6 = 1.2G (1228800 KB)
innodb_buffer_pool_size = 1228M
# 关闭 InnoDB 日志刷新到磁盘的频率,降低 I/O 压力 (牺牲少量持久性换取性能)
innodb_flush_log_at_trx_commit = 2
# 调整 Log Buffer,减少写操作
innodb_log_file_size = 256M
innodb_log_buffer_size = 32M
# 允许共享表空间,减少碎片
innodb_file_per_table = 1
# 关闭不必要的 InnoDB 功能以节省内存
innodb_stats_on_metadata = 0
innodb_adaptive_hash_index = OFF
innodb_flush_method = O_DIRECT
2. 连接与线程控制
1 核 CPU 无法处理大量并发连接,必须严格限制。
# 最大连接数:根据业务量调整,一般 50-100 即可,不要设太大
max_connections = 100
# 每个连接需要的内存估算:(max_connections * thread_stack + ... )
# 为了防止每个连接都分配大量内存,限制线程栈大小
thread_stack = 192K
# 线程缓存:1 核环境下不需要太大,保持默认或设为 10-20
thread_cache_size = 10
# 禁止使用临时文件到磁盘,尽量走内存
tmp_table_size = 32M
max_heap_table_size = 32M
3. 查询缓存与排序 (谨慎使用)
注意:MySQL 8.0 已移除 query_cache,无需配置。
# 排序缓冲区:1 核下大排序会卡死,限制其大小
sort_buffer_size = 1M
read_buffer_size = 1M
read_rnd_buffer_size = 1M
join_buffer_size = 1M
4. 日志与调试
# 降低错误日志级别,减少写入 IO
log_error_verbosity = 2
# 开启慢查询日志,但限制文件大小,防止磁盘爆满
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2 # 超过 2 秒才记录,减轻日志压力
操作系统层面的优化
除了 MySQL 配置,Linux 内核参数的调整同样重要:
1. 关闭或限制 Swap
在极端资源下,建议完全关闭 Swap,或者将其设置为仅作为最后防线。
# 查看当前 swap
free -h
# 临时关闭 (重启失效)
sudo swapoff -a
# 永久关闭:编辑 /etc/fstab,注释掉 swap 行
# 或者将 swappiness 调至最小 (0-1),告诉内核尽量不要用 swap
echo "vm.swappiness=1" >> /etc/sysctl.conf
sysctl -p
2. 调整文件系统挂载选项
如果数据盘是 ext4,建议在挂载时添加 noatime 选项,减少元数据更新带来的 IO 压力。
# 编辑 /etc/fstab,在数据盘挂载选项中添加 noatime
/dev/sdaX /data ext4 defaults,noatime 0 0
3. 设置 ulimit
防止单个用户打开文件过多导致系统崩溃。
# 编辑 /etc/security/limits.conf
mysql soft nofile 65535
mysql hard nofile 65535
mysql soft nproc 65535
mysql hard nproc 65535
运维与监控建议
-
使用轻量级存储引擎:
- 对于日志类、状态类等小表,可以考虑使用 MyISAM(虽然不支持事务,但在只读或小写入场景下极省内存)。
- 核心业务表必须使用 InnoDB。
-
索引优化:
- 在低配服务器上,索引比代码逻辑更重要。确保所有查询都有合适的索引,避免全表扫描(Full Table Scan),因为全表扫描会瞬间吃光 Buffer Pool 并导致 CPU 飙升。
-
定期清理:
- 定期执行
OPTIMIZE TABLE(注意:这会产生大量 IO,建议在业务低峰期进行)。 - 清理过大的 Binlog 和 Slow Query Log。
- 定期执行
-
监控工具:
- 安装
htop实时监控内存和 CPU。 - 关注
vmstat 1中的si(swap in) 和so(swap out) 列,如果数值持续不为 0,说明内存不足,需要进一步降低innodb_buffer_pool_size。
- 安装
总结配置示例 (/etc/my.cnf)
[mysqld]
user = mysql
port = 3306
basedir = /usr/local/mysql
datadir = /var/lib/mysql
socket = /var/lib/mysql/mysql.sock
pid-file = /var/run/mysqld/mysqld.pid
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
# --- 内存核心优化 ---
innodb_buffer_pool_size = 1228M
innodb_log_file_size = 256M
innodb_log_buffer_size = 32M
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT
innodb_file_per_table = 1
innodb_stats_on_metadata = 0
innodb_adaptive_hash_index = OFF
# --- 连接与线程 ---
max_connections = 100
thread_cache_size = 10
thread_stack = 192K
# --- 缓冲与排序 ---
tmp_table_size = 32M
max_heap_table_size = 32M
sort_buffer_size = 1M
read_buffer_size = 1M
read_rnd_buffer_size = 1M
join_buffer_size = 1M
# --- 日志 ---
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
log_error_verbosity = 2
[client]
port = 3306
socket = /var/lib/mysql/mysql.sock
default-character-set = utf8mb4
特别提示:如果部署后出现 Out of memory 错误,请优先尝试减小 innodb_buffer_pool_size(例如减至 1024M)或 max_connections。在 1C2G 环境下,稳定压倒一切,宁可牺牲一点查询速度,也要保证服务不宕机。
CLOUD云计算