【VPS 进阶玩法精选 011】VPS 上 MySQL / PostgreSQL 性能调优实战:1GB~2GB 小内存极限优化与内存档位参数表
2026-08-15 · DevCraft Studio
从 innodb_buffer_pool_size、shared_buffers 内存分配到 max_connections、慢查询日志、swap/zram 配合,手把手教你把 MySQL 和 PostgreSQL 跑在小内存 VPS 上。附真实配置片段、调优命令和按 1GB/2GB/4GB/8GB 档位划分的推荐参数表。
VPS 数据库调优 · 共 3 篇
延伸阅读
更多相关攻略推荐:【内存技术 01】DDR4 还是 DDR5?2026 年内存涨价背景、【VPS 硬件选型指南 (CPU 篇) 02】AMD EPYC vs、【跑分解读 01】别被商家的虚假宣传骗了!VPS 性能跑分全指南:Y、【VPS 硬件选型指南 (CPU 篇) 03】VPS 性价比怎么算?、【VPS 进阶玩法精选 013】Windows VPS 授权与安装完。
为什么在 VPS 上必须专门调优数据库
很多新手在 VPS 上直接 apt install mysql-server 或 apt install postgresql 之后就跑业务,结果要么内存爆满被 OOM Killer 干掉,要么 QPS 上不去、磁盘 I/O 拉满。原因很简单:MySQL 8 和 PostgreSQL 16 的出厂默认配置是按大内存服务器设计的,在 1GB~2GB 这种小内存 VPS 上,默认值要么过于激进(吃掉全部内存),要么过于保守(缓存太小导致频繁读盘)。
本篇不空谈理论,直接给你能在 Contabo、Hetzner、RackNerd、Vultr 这类 1~8GB 内存的 KVM VPS 上落地的参数。先说结论:1~2GB 内存属于"极限生存"档位,能跑轻量博客、低流量 API 和内部工具,但必须严格按下面的配置收窄;4GB 是 MySQL/PostgreSQL 生产环境的起步甜点;8GB 以上才谈得上从容。
需要强调一个心态:调优不是一次性的,而是"改配置 → 观察 → 再微调"的循环。小内存机器对参数极其敏感,照搬网上的"高性能模板"几乎必然翻车。下面每一档参数都是起点,你要在自己真实负载下用监控数据去收敛,而不是设完就再也不看。另外,数据库和应用同机时,还要给 Nginx、PHP-FPM、SSH、系统守护进程留出至少 256MB 余量,这部分常常被人忽略,结果是数据库没 OOM、SSH 却被挤到连不上。
第一步:先摸清家底(内存、磁盘 I/O、当前占用)
动手改配置前,先确认你到底有多少可用内存、磁盘是 SSD 还是 NVMe、数据库现在吃了多少。三个命令就够了:
free -h
swapon --show
lsblk -o NAME,ROTA,SIZE,MODEL # ROTA=0 表示 SSD/NVMe再测一下磁盘顺序读写,判断是不是 NVMe(小内存 VPS 上 NVMe 对数据库帮助极大,random_page_cost 可以直接从默认的 4.0 降到 1.1):
fio --name=randread --ioengine=libaio --rw=randread --bs=4k --numjobs=4 --size=1G --runtime=60 --group_reporting看 MySQL 当前缓冲池有没有生效、命中率如何:
mysql -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"
mysql -e "SHOW STATUS LIKE 'Innodb_buffer_pool_read%';"Innodb_buffer_pool_reads 与 Innodb_buffer_pool_read_requests 的比值越小越好,比值高说明缓冲池太小、经常回磁盘读。
MySQL 在小内存 VPS 上的核心调优
1. innodb_buffer_pool_size:最重要的一个参数
缓冲池是 InnoDB 缓存数据和索引的地方,是 MySQL 内存里最大的消费者。经验法则是设为物理内存的 50%~60%,给 OS 和其他进程(PHP-FPM、Nginx、SSH)留出空间。注意 MySQL 8 默认会"自动调大"缓冲池,在 2GB 机器上可能直接占掉 1GB 以上,导致别的进程被挤爆。
# /etc/mysql/mysql.conf.d/mysqld.cnf (MariaDB 在 /etc/mysql/mariadb.conf.d/50-server.cnf)
[mysqld]
innodb_buffer_pool_size = 1G # 2GB 机器:约 50%~60%
innodb_buffer_pool_instances = 1 # 缓冲池 < 1GB 时用单实例,多实例反而增加开销1GB 机器就降到 256M,并配合单实例:
[mysqld]
innodb_buffer_pool_size = 256M
innodb_buffer_pool_instances = 12. max_connections:别给每个连接都留内存
默认 151 个连接对 Dedicated 服务器合理,但对小内存 VPS 太高——每个连接都会吃几 MB 的排序/读缓冲。低流量应用 50 足够,单应用开发环境甚至 25 即可。配合应用层连接池(如 HikariCP、ProxySQL)效果更好。
[mysqld]
max_connections = 503. 关闭 performance_schema,省下 100~200MB
这是诊断用的内存表,小内存机器上性价比极低。线上排查可以改用慢查询日志和 pt-query-digest。
[mysqld]
performance_schema = OFF4. 收紧每会话缓冲与临时表
[mysqld]
sort_buffer_size = 512K
join_buffer_size = 512K
read_buffer_size = 512K
read_rnd_buffer_size = 512K
tmp_table_size = 64M
max_heap_table_size = 64M
innodb_log_buffer_size = 8M5. 打开慢查询日志,揪出真凶
光调内存不够,慢 SQL 才是性能黑洞。开启慢查询日志,超过 1 秒的记录下来:
[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
log_queries_not_using_indexes = 1改完先校验语法再重启:
mysqld --validate-config
systemctl restart mysql
# MariaDB 用: systemctl restart mariadbPostgreSQL 在小内存 VPS 上的核心调优
1. shared_buffers:PostgreSQL 自己的页缓存
PostgreSQL 出厂默认非常保守,shared_buffers 往往只有 128MB。经验值设为物理内存的 25%,超过 25% 收益递减(因为 Linux 内核页缓存也在缓存同样的块)。2GB 机器设 512MB,1GB 机器设 256MB 甚至 128MB。
# /etc/postgresql/16/main/postgresql.conf (用 SHOW config_file; 确认实际路径)
shared_buffers = 512MB # 2GB 机器:约 25%
effective_cache_size = 1500MB # 约 75%,告诉规划器 OS+PG 一共能热多少数据2. work_mem:最容易 OOM 的陷阱
这是每个排序/哈希节点的内存预算,不是每连接!一条带 3 个排序节点的查询会吃掉 3 倍 work_mem,再乘以并发数就可能瞬间 OOM。小内存机器上务必保守:
work_mem = 8MB # 2GB 机器
# work_mem = 4MB # 1GB 机器更保守
maintenance_work_mem = 128MB # VACUUM / CREATE INDEX 用,1GB 机器降到 64MB3. 降低 max_connections,用 PgBouncer 扛并发
每个 PG 连接要占 5~10MB,100 个连接还没跑查询就吃掉 0.5~1GB。降到 20~50,再用 PgBouncer 在事务级别复用连接:
max_connections = 50
checkpoint_completion_target = 0.9
random_page_cost = 1.1 # SSD/NVMe 环境从 4.0 降到 1.1,让规划器更爱用索引安装并配置 PgBouncer(事务池模式最省内存):
sudo apt install pgbouncer
# /etc/pgbouncer/pgbouncer.ini
[databases]
mydb = host=127.0.0.1 port=5432 dbname=mydb
[pgbouncer]
listen_addr = 127.0.0.1
listen_port = 6432
pool_mode = transaction
default_pool_size = 25
max_client_conn = 2004. 慢查询日志与热点分析
log_min_duration_statement = 200 # 记录超过 200ms 的语句
log_connections = on
log_disconnections = on找出真凶用 EXPLAIN 看缓冲命中,再用 pg_stat_statements 定位总耗时最高的 SQL:
sudo -u postgres psql -c "CREATE EXTENSION IF NOT EXISTS pg_stat_statements;"
EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM orders WHERE user_id = 42 ORDER BY created_at DESC;小内存(1GB~2GB)VPS 的极限优化与 swap/zram
1~2GB 机器上,数据库 + 应用同机,物理内存经常不够。swap/zram 是你的最后一道防线,但用错方式反而拖死性能。要点:
- 优先用 zram 而不是传统磁盘 swap。zram 用压缩内存当交换区,速度比磁盘 swap 快几个数量级,特别适合内存紧张的小 VPS。多数现代发行版(Ubuntu 22.04+/Debian 12+)已默认启用 zram,可用
zramctl查看。 - 传统磁盘 swap 要设 swappiness 偏低,避免数据库频繁被换出。建议
vm.swappiness=10,并设vm.vfs_cache_pressure=50保护目录缓存。 - 给 MySQL 加内存上限保护:通过 systemd 的 MemoryMax 限制,避免它把整台机器拖垮。
# 查看 zram
zramctl
swapon --show
# 调低 swappiness(写入 /etc/sysctl.d/99-vps.conf)
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.d/99-vps.conf
echo 'vm.vfs_cache_pressure=50' | sudo tee -a /etc/sysctl.d/99-vps.conf
sudo sysctl --system
# 给 MySQL 套内存上限(/etc/systemd/system/mysql.service.d/limits.conf)
[Service]
MemoryMax=1500M对 PostgreSQL,用 vm.overcommit_memory=2 + vm.overcommit_ratio 防止 OOM,并配置 oom_score_adj 让 postmaster 不被优先杀掉:
echo 'vm.overcommit_memory=2' | sudo tee -a /etc/sysctl.d/99-vps.conf
sudo sysctl --system
sudo systemctl edit postgresql
# 在编辑器中加入:
[Service]
OOMScoreAdjust=-500不同内存档位的推荐参数表
下面是经过多个小内存 VPS 实测的推荐起点值。所有档位都假设数据库与应用同机,请按实际负载微调(切忌直接照搬后不监控)。
| 内存档位 | MySQL innodb_buffer_pool_size | MySQL max_connections | PG shared_buffers | PG work_mem | PG effective_cache_size | PG max_connections |
|---|---|---|---|---|---|---|
| 1GB | 256M | 30~50 | 256M | 4MB | 512M | 20~30 |
| 2GB | 1G | 50~100 | 512M | 8MB | 1500M | 50 |
| 4GB | 2G | 150 | 1GB | 16MB | 3GB | 100 |
| 8GB | 4~5G | 300 | 2GB | 32~64MB | 6GB | 200 |
小内存档位额外建议:performance_schema=OFF(MySQL)、pgbouncer 事务池(PG)、开启 zram、关闭不需要的二进制日志(测试环境)。调优后用 free -h 和数据库内部状态观察,命中率上去了、swap 几乎不波动,才说明配置对了。
选型参考:四家 VPS 厂商的内存与价格(2026)
调优能救小内存,但选对机器更省心。下面是 2026 年四家厂商的内存档位与月付/年付参考(价格随活动波动,以官网为准):
- RackNerd:KVM 架构,SSD RAID-10,1Gbps。1GB 年付约 $21.99/年(约 $1.8/月),2GB 约 $35.99/年,4GB 约 $59.99/年;机房集中在洛杉矶、圣何塞、达拉斯等美国节点,支持支付宝/PayPal,是极限优化练手的首选便宜货。
- Hetzner:CX 系列共享 vCPU,NVMe,20TB 流量。CX22(2 vCPU/4GB/40GB NVMe)约 €4.35/月(~$4.65),CX32(4 vCPU/8GB)约 €7.59/月;德国/芬兰/美东/新加坡机房,DDoS 防护和 IPv4/IPv6 免费,性价比甜点档。
- Contabo:同价位给的 RAM 最多。Cloud VPS 10(3 vCPU/8GB/75GB NVMe/32TB)约 €4.50/月,VPS S(4 vCPU/8GB)约 $4.99~7.99/月;缺点是非独享 CPU、SLA 99.0%、入站免费出站 32TB,适合 RAM 是瓶颈的数据库场景。
- Vultr:全球 32+ 机房、按小时计费。Regular 1GB 约 $5~6/月,2GB 约 $10~12/月,4GB 约 $20~24/月;High Frequency(AMD EPYC + NVMe)单核更强,新用户有 $100~300 试用额度,适合需要就近低延迟节点的业务。
调优之后如何验证效果(监控与回滚)
改完配置不是终点,必须验证是否真的变快、是否稳定。最实用的两个观察点是内存和缓冲命中率。用 free -h 看 available 是否长期为正、swap 是否几乎不动;用数据库自带状态看缓存命中。不要只信"感觉快了",要用数字说话。
# MySQL 缓冲池命中率(结果越接近 1 越好)
mysql -e "SELECT 1 - (Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests) AS hit_rate FROM (SELECT VARIABLE_VALUE AS Innodb_buffer_pool_reads FROM information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME='Innodb_buffer_pool_reads') r, (SELECT VARIABLE_VALUE AS Innodb_buffer_pool_read_requests FROM information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME='Innodb_buffer_pool_read_requests') q;"PostgreSQL 侧用 pg_stat_database 看 blk_hit 占比,配合 pg_stat_statements 的 mean_exec_time 找出仍需优化的慢 SQL。任何改动都建议先 cp 备份原配置(例如 postgresql.conf.bak、mysqld.cnf.bak),一旦重启后连不上或负载异常,立刻回滚并对比前后指标。
还有一个常被忽视的点:应用层必须配合。再好的数据库参数也救不了 SELECT *、缺失索引和 N+1 查询。上线前用 EXPLAIN 逐条确认执行计划走了索引,给 WHERE、JOIN、ORDER BY 字段补上索引,并把热点数据放进 Redis,这往往比继续加内存收益更大。调优的尽头永远是从"堆资源"转向"改写法"。
💡 延伸阅读:关于架构与基础设施的更多深潜指南,请前往 VPS 主题导读中心 (Hub) 获取全盘策略。