努力
加油

CentOS 7或Ubuntu 22.04上安装MySQL 8.0,1核2G配置需要哪些优化设置?

1核2G的机器跑MySQL 8.0,说实话,压力不小。MySQL 8.0相比5.7,内存占用和CPU开销都上去了,尤其是InnoDB缓冲池默认配置如果不调整,很容易直接OOM(Out of Memory)或者Swap交换导致数据库假死。

在云服务器这种资源受限的环境下,我们的核心目标只有一个:保活。即确保数据库服务不崩溃,响应不至于慢到无法接受。不要追求高并发,先保证单连接或少量连接下的稳定性。

以下是针对CentOS 7或Ubuntu 22.04安装MySQL 8.0后的具体优化方案,按优先级排序:

1. 核心参数调优(my.cnf / mysql.cnf)

这是最关键的一步。你需要编辑 /etc/my.cnf (CentOS) 或 /etc/mysql/mysql.conf.d/mysqld.cnf (Ubuntu)。

建议添加/修改以下参数:

[mysqld]
# --- 基础设置 ---
user=mysql
port=3306
basedir=/usr
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

# --- 字符集 ---
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci

# --- 关键内存优化 (1C2G的核心) ---
# InnoDB缓冲池是MySQL性能的灵魂。
# 物理内存2G,扣除系统和其他进程,留给MySQL的安全内存大约在1G-1.2G左右。
# 默认innodb_buffer_pool_size是128M,太小;如果设为1.5G又太冒险。
# 建议设置为 1G (1024M) 或 1280M。
innodb_buffer_pool_size = 1G

# 如果数据量极小(<1GB),可以考虑单实例,否则保持默认1
innodb_buffer_pool_instances = 1

# 日志文件大小。适当增大可以减少刷盘频率,提升写入性能,但故障恢复时间变长。
# 对于1G内存,设大点没关系,反正不会占太多额外内存。
innodb_log_file_size = 256M

# 检查点机制,平衡读写性能
innodb_flush_log_at_trx_commit = 2 
# 解释:1是最安全(每次事务都同步到磁盘),2是每秒同步一次。
# 在1C2G且非XX级业务场景下,强烈建议改为2,能显著降低I/O压力。
# 如果业务对数据一致性要求极高,请保留1,但需做好SSD硬盘准备。

innodb_flush_method = O_DIRECT
# 避免操作系统缓存与InnoDB自身缓存冲突,减少内存浪费。

# --- 连接数优化 ---
# 1核CPU处理不了太多并发线程。
# max_connections设得太高会导致上下文切换频繁,CPU飙升。
# 建议根据实际业务需求,通常Web应用配合连接池,DB端无需太高。
max_connections = 150

# 每个连接的线程栈大小,默认8M,1核2G可以适当减小
thread_stack = 256K

# --- 临时表优化 ---
# 内存临时表上限,超过则落盘
tmp_table_size = 64M
max_heap_table_size = 64M

# --- 查询缓存 (注意:MySQL 8.0已移除query_cache) ---
# 如果你是从5.7升级上来的配置文件,记得删掉 query_cache_type 和 query_cache_size,否则会报错。

# --- 日志设置 ---
# 关闭慢查询日志,除非你正在排查问题,否则它会消耗IO。
# slow_query_log = 1
# long_query_time = 2
# slow_query_log_file = /var/log/mysql/slow.log

# 通用日志,生产环境建议关闭
general_log = 0

关于 innodb_buffer_pool_size 的特别说明:
在Linux系统中,内核本身需要预留一部分内存用于文件缓存等。如果你的服务器只跑MySQL这一项重型服务,可以尝试将 innodb_buffer_pool_size 设为总内存的70%-75%。但在1C2G这种极限配置下,保守起见设为 1G 是最稳妥的。你可以监控 SHOW ENGINE INNODB STATUSG 中的 Buffer pool hit rate,如果命中率低于98%,说明内存不够,可能需要考虑增加内存或优化SQL。

2. 操作系统层面的优化

MySQL的性能瓶颈往往不在配置,而在OS层面。

A. Swap 分区处理

1核2G机器极易触发Swap。Swap会严重拖慢数据库性能,因为磁盘速度比内存慢几个数量级。

  • 方案一(推荐): 如果可能,创建Swap文件,但将其优先级降到最低,或者在MySQL启动脚本中通过 sysctl vm.swappiness=10 抑制内核使用Swap的倾向。
  • 方案二(激进): 完全禁用Swap。如果MySQL OOM了,它会被系统杀死,然后你可以重启它。这比它在Swap里慢慢卡顿要好控制得多。
    # 临时禁用
    sudo swapoff -a
    # 永久禁用,注释掉 /etc/fstab 中的swap行

B. I/O 调度器

查看当前I/O调度器:

cat /sys/block/vda/queue/scheduler

对于云服务器(通常是NVMe SSD或高性能云盘),建议使用 none 或 mq-deadline。如果是HDD,用 deadline。
修改方法(以CentOS为例,Ubuntu类似):

echo "none" > /sys/block/vda/queue/scheduler
# 需写入 rc.local 或 systemd service 实现开机生效

C. NUMA 设置

大多数云服务器是多路CPU或多核模拟,NUMA可能会带来性能抖动。

# 检查是否启用NUMA
numactl --hardware
# 如果有多节点,建议在my.cnf中添加:
# innodb_numa_interleave = 1
# 或者在启动命令中加入 numactl --interleave=all

对于单核2G,这个影响较小,可忽略。

3. MySQL 8.0 特有注意事项

  • 密码插件: MySQL 8.0 默认使用 caching_sha2_password。虽然更安全,但部分旧版客户端驱动兼容性不好。如果遇到连接问题,可以改回 mysql_native_password:
    ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password';
    FLUSH PRIVILEGES;
  • SSL/TLS: MySQL 8.0 强制要求SSL连接(在某些认证插件下)。如果内网通信,可以生成自签名证书或在配置文件中设置 require_secure_transport=OFF(不推荐生产环境,但开发测试方便)。
  • JSON 支持: MySQL 8.0 对JSON有原生支持,但如果你的应用大量使用JSON字段,注意索引效率。MySQL 8.0 引入了虚拟列索引,可以利用这一点优化JSON查询。

4. 运维与监控建议

  1. 定期清理二进制日志:

    PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 3 DAY);

    或者在配置文件中设置 expire_logs_days = 3。防止日志撑爆磁盘。

  2. 监控工具:
    不要依赖复杂的Prometheus+Grafana(资源不够)。使用简单的 top, htop, iotop 即可。
    重点观察:

    • load average:长期高于2就要警惕。
    • wa (iowait):如果很高,说明磁盘IO成为瓶颈。
    • si/so (swap in/out):如果swap活跃,立即扩容或优化SQL。
  3. SQL优化是第一要务:
    在1C2G环境下,一个全表扫描的SQL就能让CPU打满。务必开启慢查询日志进行排查,确保所有查询都有索引覆盖。

总结

在1核2G上运行MySQL 8.0,“稳”字当头。

  1. 将 innodb_buffer_pool_size 设为 1G。
  2. 将 innodb_flush_log_at_trx_commit 设为 2(权衡性能与安全)。
  3. 限制 max_connections 在 150 以内。
  4. 尽量禁用或抑制Swap。
  5. 代码层做好连接池管理,避免短连接频繁创建销毁。

如果业务增长,发现CPU持续100%或内存经常不足,第一反应不是优化MySQL,而是加内存或分库分表/读写分离。硬件瓶颈靠软件优化是有天花板的。