MySQL/MariaDB 是搬瓦工 VPS 上最常部署的数据库之一。默认配置针对通用场景,对小内存 VPS 而言往往过于保守或存在性能瓶颈。本文从缓冲池、连接数、慢查询日志等核心维度出发,给出适合搬瓦工小型 VPS(512 MB ~ 2 GB 内存)的实用调优方案,并提供完整的 my.cnf 配置示例。

本文要点

  • innodb_buffer_pool_size 是最重要的单个参数,设为物理内存的 50%~70%
  • 合理设置连接数,避免内存耗尽
  • 开启慢查询日志,定位性能瓶颈 SQL
  • 每次改动后重启数据库并观察一段时间

调优前的准备

  • 记录当前数据库状态:SHOW GLOBAL STATUS;
  • 确认内存大小:free -h
  • 备份现有配置:cp /etc/mysql/my.cnf /etc/mysql/my.cnf.bak
  • 调优是逐步迭代的过程,每次只改 1~2 个参数再观察

InnoDB 缓冲池调优

innodb_buffer_pool_size 是 MySQL 最重要的参数,控制 InnoDB 在内存中缓存数据和索引的空间。设置越大,磁盘 I/O 越少,查询越快:

VPS 内存建议 buffer_pool_size说明
512 MB128~256 MB留出足够空间给 OS 和其他进程
1 GB512~700 MBMySQL 专用场景可到 70%
2 GB1 GB~1.4 GB业务复杂时留余量
4 GB+2~3 GB大缓冲池,明显减少磁盘 I/O
# 在 [mysqld] 段添加或修改
[mysqld]
innodb_buffer_pool_size = 512M    # 根据内存调整
innodb_buffer_pool_instances = 2  # 内存 > 1GB 时建议 2~4
innodb_log_file_size = 128M       # 越大批量写越快,但崩溃恢复慢
innodb_flush_log_at_trx_commit = 2  # 1=最安全,2=性能好(每秒刷盘)
innodb_flush_method = O_DIRECT    # 跳过 OS 缓存,避免双重缓存

innodb_flush_log_at_trx_commit 的权衡

设为 1(默认):每次提交都刷盘,最安全但 I/O 压力大。设为 2:事务提交写内存日志,每秒刷盘一次,性能提升明显,极端情况下(宕机)最多丢失 1 秒数据。对不要求零丢失的业务(博客、展示站),设为 2 是合理选择。

连接数配置

连接数过多会大量消耗内存(每个连接约消耗 1~10 MB),需要根据实际并发量合理设置:

[mysqld]
max_connections = 100        # 小 VPS 建议 50~150,避免 OOM
wait_timeout = 600           # 空闲连接超时(秒)
interactive_timeout = 600    # 交互式连接超时
thread_cache_size = 16       # 线程缓存,减少频繁创建销毁开销

开启慢查询日志

慢查询日志是找出性能瓶颈 SQL 的最直接手段:

[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1           # 执行超过 1 秒的 SQL 记入慢查询
log_queries_not_using_indexes = 1  # 未用索引的查询也记录
# 分析慢查询日志
mysqldumpslow -s t -t 20 /var/log/mysql/slow.log
# -s t 按总耗时排序,-t 20 只显示前 20 条

其他常用优化参数

[mysqld]
tmp_table_size = 64M           # 内存临时表大小上限
max_heap_table_size = 64M      # MEMORY 引擎表大小
query_cache_type = 0           # MySQL 8.0 已移除,5.7 可关闭减少锁竞争
open_files_limit = 65535       # 打开文件数上限(需配合系统 ulimit)
skip_name_resolve = 1          # 跳过 DNS 反向解析,加快连接建立

完整 my.cnf 示例(1 GB 内存 VPS)

以上参数综合起来,一台 1 GB 内存的搬瓦工 VPS 运行 WordPress + MySQL 的参考配置:buffer_pool_size=512Mmax_connections=80flush_log=2slow_query_log=1,基本能覆盖日均 5000~20000 PV 的博客或展示站需求。

监控数据库状态

-- 查看缓冲池命中率(应 > 99%)
SHOW GLOBAL STATUS LIKE "Innodb_buffer_pool_reads";
SHOW GLOBAL STATUS LIKE "Innodb_buffer_pool_read_requests";

-- 查看当前连接
SHOW PROCESSLIST;

-- 查看慢查询计数
SHOW GLOBAL STATUS LIKE "Slow_queries";

小结

  • innodb_buffer_pool_size 优先调,设为内存的 50%~70%
  • 连接数根据并发量设,过高会导致内存耗尽
  • 慢查询日志是定位 SQL 瓶颈的必备工具
  • 改参数要逐步测试,每次改完重启并观察一天再继续

常见问题

MariaDB 和 MySQL 的调优参数一样吗?

绝大多数参数相同,MariaDB 在 InnoDB 替代(Aria/XtraDB)上有额外参数,但针对 InnoDB 的调优参数两者通用,本文示例可直接用于 MariaDB。

改完 my.cnf 后数据库启动失败怎么办?

先用 mysqld --validate-config 检查配置语法;或查看错误日志 /var/log/mysql/error.log。有问题时可用备份的 my.cnf.bak 恢复。

缓冲池命中率低于 95%,怎么优化?

说明频繁需要从磁盘读数据,应适当增大 innodb_buffer_pool_size。同时检查是否有没有用索引的全表扫描,给高频查询字段加索引往往比增大缓冲池效果更好。

怎么查看 MySQL 当前实际内存占用?

ps aux | grep mysql 查看进程 RSS 内存;或在 MySQL 内执行 SELECT * FROM performance_schema.memory_summary_global_by_event_name ORDER BY CURRENT_NUMBER_OF_BYTES_USED DESC LIMIT 10;(需开启 performance_schema)。