跑数据库的VPS该选多大内存,这个问题在论坛里得到的答案往往两极分化。有人说2G够用,有人开口就是8G起步。两种说法可能都没错,但它们对应的负载场景完全不同。真正容易被忽略的是中间那个变量:MySQL 在你不改任何配置、装完就跑的情况下,自己会吃掉多少内存。如果这个底数没算清楚,你选配置时就是在猜,而不是在算。
默认配置下的 MySQL 并不是“轻量”的
MySQL 8.0 的默认配置有一个明确的设计目标:让服务器能在约 512MB 内存的虚拟机上启动。注意措辞,是“启动”,不是“跑得动业务”。启动和运行是两回事。默认配置为了让 MySQL 能在极小内存的机器上完成初始化,把很多参数压得很低,但即便如此,一个空载的 MySQL 8.0 实例在启动后占用的常驻内存,通常也在 200MB 到 400MB 之间,取决于编译选项和启用的组件。
这个数字放在 1GB 内存的 VPS 上,意味着系统本身、SSH 守护进程、可能的监控 agent 还没算进去,MySQL 已经先拿走了一小半。如果再跑一个 Web 服务或者应用进程,可用内存很快就见底了。而一旦内存紧张触发 OOM Killer,第一个被盯上的往往就是 MySQL,因为它是 RSS 最大的那个进程。表现出来的现象是数据库莫名其妙地“挂了”,重启后又正常,过一阵再次发生。很多人以为是 MySQL 有 bug,实际上是内存从一开始就没留够。
InnoDB 缓冲池:那个你不动它就不动的默认值
innodb_buffer_pool_size 是 MySQL 内存讨论里绕不开的参数,因为 InnoDB 是默认存储引擎,而缓冲池是它缓存数据和索引的地方。这个参数的默认值在 MySQL 8.0 里是 134217728 字节,也就是 128MB。
128MB 的缓冲池对于任何有实际数据量的业务来说都是不够的。它的作用是把热数据和索引留在内存里,避免每次查询都去读磁盘。缓冲池越小,磁盘 I/O 越频繁,查询延迟越高。在机械盘或者低端 SSD 的 VPS 上,这种性能衰减会非常明显。但问题在于,如果你不主动去调大它,MySQL 就安安静静地用着 128MB,不会报错,不会告警,只是慢。你以为是 VPS 的 CPU 不行或者磁盘太差,实际上是缓冲池太小导致的。
合理的做法是把缓冲池设置为可用内存的 50% 到 70%。但这个“可用内存”指的是系统总内存减去操作系统自身开销、其他必要进程、以及 MySQL 自身除缓冲池之外的其他内存开销之后剩下的部分。如果你在 2GB 的机器上直接把缓冲池设成 1.4GB(70%),系统和其他进程就只能挤在剩下的 600MB 里,风险很大。
除了缓冲池,MySQL 还在悄悄用这些内存
把目光只盯在缓冲池上是不够的。MySQL 8.0 的 Performance Schema 是另一个默认开启的内存消耗者。它的内存分配模型和传统参数不同:内部缓冲区初始为空,随着负载增加逐步分配,而且在服务器运行期间从不释放,尽管可能会被回收。这意味着 Performance Schema 占用的内存会随着你业务查询的复杂度、连接数、监控需求的增长而爬升,但它不会自己降回来。
你可以通过一条查询看到它实际占了多少:
SELECT * FROM performance_schema.memory_summary_global_by_event_name
WHERE EVENT_NAME LIKE 'memory/performance_schema/%';
在负载不高的实例上,这个数字可能只有几十 MB。但在连接数多、查询种类繁杂的场景下,它可能膨胀到几百 MB。如果你按照“缓冲池 = 总内存 × 70%”来分配,完全没有给 Performance Schema 留出增长空间,运行一段时间后就会出问题。
还有连接层面的内存。每个数据库连接都会分配读缓冲区、排序缓冲区、连接缓冲区等。这些参数的单次分配量不大,但乘以并发连接数就不一样了。max_connections 默认是 151,如果每个连接的综合缓冲区开销在几 MB 级别,满载时就是几百 MB 的额外占用。这些内存不是启动时就占住的,而是在并发上来后才逐渐吃掉,所以从监控图上看,内存曲线会随着业务高峰同步上扬。
按场景倒推,而不是按“够不够”来猜
与其问“2G 够不够”,不如先确定你的数据量和并发量,再倒推内存需求。
对于个人项目、开发环境、或者数据量在几百 MB 以内的小型应用,2GB 内存的 VPS 是可以跑起来的。但前提是你需要做一次基本的调优:把缓冲池设到 512MB 左右,关闭不必要的 Performance Schema 消费者以减少内存增长,限制 max_connections 到一个合理的值(比如 50 而不是默认的 151)。这样 MySQL 本身占用的内存大约在 800MB 到 1GB 之间,剩下的留给系统和其他轻量进程。如果不做任何配置调整,直接用默认值跑,2GB 机器上 MySQL 加上系统开销大概率能撑住,但缓冲池只有 128MB,性能表现会和你对一台数据库服务器的预期有差距。
当你的数据量超过 1GB,或者日活跃请求开始产生持续的并发查询时,2GB 就不再是一个舒适的选择了。缓冲池需要至少覆盖热数据的大小,才能让查询不频繁落到磁盘上。如果热数据有 2GB,缓冲池就需要 2GB 以上,加上 MySQL 其他开销和系统占用,整机内存至少要 4GB 起步。建议是轻量应用 2 核 4G 起步,中小型业务 4 核 8G 到 4 核 16G,CPU 与内存的比例在 1:2 到 1:4 之间比较合理。这个比例背后的逻辑是 MySQL 对内存的敏感度远高于对 CPU 核心数的敏感度:内存不够直接导致 I/O 瓶颈,而 CPU 核心多一点少一点,在并发不极端的情况下差异没有那么大。
还有一个容易被忽略的细节:VPS 上通常不只跑 MySQL 一个东西。如果你在同一台机器上还放了应用服务、Redis、或者 Nginx,这些进程都需要从总内存里分走一块。把 MySQL 缓冲池按“总内存 × 70%”来设,等于假设整台机器是 MySQL 独占的。在混合部署的 VPS 上,更安全的做法是先扣掉其他进程的预估占用,再按剩余内存的 50% 到 60% 来设缓冲池。
如果你正在选一台跑 MySQL 的 VPS,而且不确定业务会发展到什么程度,4GB 内存是一个比 2GB 更不容易后悔的起点。在这个配置上,你可以把缓冲池设在 1.5GB 到 2GB 之间,给 Performance Schema 和连接开销留出余量,同时系统本身和其他轻量进程还有空间。如果预算紧张必须选 2GB,那就必须接受“装完要调”这个前提,不能指望默认配置能给出可接受的性能。
选配置的时候,与其看商家页面上“适合数据库”的标签,不如在买之前就想清楚:你的数据量大概多大,热数据占多少,并发连接峰值大概是多少。把这三个数估出来,缓冲池的大小就有了下限,整机内存的大小也就有了依据。MySQL 不会因为你没调参数就停止消耗内存,它只是换了一种方式——用磁盘 I/O 和查询延迟来偿还那部分被省下的内存。
推荐文章