速卖通素材
奋斗

CentOS或Ubuntu系统上,2核4G服务器如何优化MySQL 8.0性能?

服务器

在 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 秒事务)。
  • 务必执行 sysbenchmysqltuner.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 仍是瓶颈:

  1. 开启慢查询日志分析

    SHOW VARIABLES LIKE 'slow_query_log';
    SHOW VARIABLES LIKE 'long_query_time';

    定期分析 /var/log/mysql/slow.log 或使用 pt-query-digest(Percona Toolkit)。

  2. 强制使用索引

    • 检查 EXPLAIN SELECT ...,确保 typeref/range/const,避免 ALL
    • 对高频 WHERE/JOIN 字段建立复合索引(注意顺序:左前缀原则)。
  3. 避免全表扫描与大事务

    • 分页查询用 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 » CentOS或Ubuntu系统上,2核4G服务器如何优化MySQL 8.0性能?