在 2 核 4G 的服务器上运行 MySQL 8.0,资源相对紧张(尤其是内存),优化核心在于合理分配内存、减少 I/O 等待、避免 CPU 争用。以下是针对 CentOS/Ubuntu 的实战优化方案:
一、关键配置调整(my.cnf / mysql.cnf)
编辑配置文件(通常位于 /etc/my.cnf 或 /etc/mysql/mysql.conf.d/mysqld.cnf),在 [mysqld] 段添加/修改以下参数:
[mysqld]
# 基础设置
datadir = /var/lib/mysql
socket = /var/run/mysqld/mysqld.sock
pid-file = /var/run/mysqld/mysqld.pid
# 内存分配(核心!4G 服务器建议保留 ~1.5G 给 OS 和其他服务)
innodb_buffer_pool_size = 1.5G # 占物理内存 75% 左右(最大可设到 2.5G,但需预留 OS 缓存空间)
innodb_log_file_size = 512M # 增大日志文件,减少刷盘频率
innodb_flush_log_at_trx_commit = 2 # 权衡安全与性能:0=极快但不安全;1=最安全;2=每秒落盘(推荐折中)
innodb_flush_method = O_DIRECT # 避免双重缓冲,减少系统调用开销
# 连接与线程
max_connections = 150 # 根据业务负载调整,默认 151 较合理
thread_cache_size = 32 # 缓存线程,减少创建开销
skip_name_resolve = ON # 禁用 DNS 解析,加快连接速度
# 查询缓存(MySQL 8.0 已移除 query_cache,无需配置)
# 注意:MySQL 8.0 不支持 query_cache,切勿尝试启用
# InnoDB 其他优化
innodb_read_io_threads = 4
innodb_write_io_threads = 4
innodb_purge_threads = 2
innodb_file_per_table = ON # 每个表独立文件,便于管理
table_open_cache = 400 # 根据实际表数量调整
open_files_limit = 65535 # 提高文件句柄限制
# 临时表处理
tmp_table_size = 64M
max_heap_table_size = 64M
# 日志与监控
slow_query_log = ON
long_query_time = 2 # 记录超过 2 秒的慢查询
log_queries_not_using_indexes = ON # 记录未使用索引的查询
✅ 重要提示:
innodb_buffer_pool_size是最关键参数。若服务器仅跑 MySQL,可设为 2.5G~3G;若同时运行 Nginx/PHP/Redis 等,建议 ≤1.5G。innodb_flush_log_at_trx_commit = 2在保证数据不丢失的前提下显著提升写入性能(断电可能丢最近 1 秒事务)。- 务必执行
sysbench或mysqltuner.pl验证配置合理性。
二、操作系统级优化(CentOS/Ubuntu 通用)
1. 文件系统与挂载选项
- 将
/var/lib/mysql所在分区格式化为 XFS(CentOS 默认)或 ext4(Ubuntu 推荐),并启用noatime:# /etc/fstab 示例 /dev/sda1 /var/lib/mysql xfs defaults,noatime,nodiratime 0 0 - 重启后生效:
mount -o remount /var/lib/mysql
2. 内核参数调优(/etc/sysctl.conf)
# 增加 TCP 连接池
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
# 提升文件描述符限制
fs.file-max = 65535
# 虚拟内存策略(允许更多页面缓存)
vm.swappiness = 10
vm.vfs_cache_pressure = 50
应用:sudo sysctl -p
3. 关闭不必要服务 & 设置 SELinux/AppArmor
- CentOS:
systemctl stop firewalld(或用firewall-cmd --set-default-zone=trusted谨慎开放端口)
setenforce 0(测试环境可临时关闭,生产建议配置规则而非完全关闭) - Ubuntu:
ufw disable或仅放行 3306 + 80/443
三、SQL 与索引优化(同等重要!)
即使硬件升级,低效 SQL 仍是瓶颈:
-
开启慢查询日志分析:
SHOW VARIABLES LIKE 'slow_query_log'; SHOW VARIABLES LIKE 'long_query_time';定期分析
/var/log/mysql/slow.log或使用pt-query-digest(Percona Toolkit)。 -
强制使用索引:
- 检查
EXPLAIN SELECT ...,确保type为ref/range/const,避免ALL。 - 对高频 WHERE/JOIN 字段建立复合索引(注意顺序:左前缀原则)。
- 检查
-
避免全表扫描与大事务:
- 分页查询用
WHERE id > last_id LIMIT 10替代OFFSET。 - 大事务拆分为小批次提交。
- 分页查询用
四、监控与持续调优
-
安装监控工具:
# Ubuntu sudo apt install prometheus-node-exporter grafana # CentOS sudo yum install epel-release && sudo yum install prometheus-node-exporter -
使用
mysqldumpslow或 Percona Toolkit 的pt-summary快速诊断:sudo apt install percona-toolkit # Ubuntu sudo yum install percona-toolkit # CentOS (需 EPEL) pt-summary --user=root --password=xxx -
定期备份 + 清理归档日志,防止磁盘爆满。
五、进阶建议(如仍遇瓶颈)
| 问题类型 | 解决方案 |
|---|---|
| 高并发读多写少 | 引入 Redis 缓存热点数据 |
| 写入压力过大 | 分库分表(Sharding)、异步队列削峰 |
| 磁盘 I/O 成为瓶颈 | 更换 SSD/NVMe;考虑 RAID 10(成本较高) |
| CPU 频繁 100% | 检查是否存在死循环 SQL、触发器过多、统计信息过期(ANALYZE TABLE) |
✅ 最后提醒:
所有配置修改后,务必重启 MySQL:
sudo systemctl restart mysqld
并在重启前备份数据:
mysqldump --all-databases > full_backup_$(date +%F).sql
如需进一步定制(例如特定业务场景:电商订单、日志分析等),可提供具体负载特征,我可给出更针对性的方案。
轻量云Cloud