如果你在 AWS 上跑 PostgreSQL,这两天有个坏消息得知道。

AWS 工程师 Salvatore Dipietro 最近做了个测试,把 Linux 7.0 跑在 Graviton4(ARM64 架构)服务器上跑 PostgreSQL——结果吞吐量只剩上一代内核的 51%,延迟还蹭蹭往上涨。一行代码改动,数据库性能直接对半砍。

说实话,第一次看到这个数字我以为是测试方法有问题。但人家是 AWS 工程师,做了内核二分定位,把出问题的 commit 都锁定了。这事儿不是玄学,是硬邦邦的事实。

一行代码,怎么把数据库打残的?

问题出在 Linux 7.0 对内核调度器的可用抢占模式做了限制。

之前的 Linux 版本有个叫 PREEMPT_NONE 的模式,说白了就是告诉内核:”对于服务器优化的工作负载,你别随便插队,让它跑完再说。” PostgreSQL 这种数据库,高并发下一堆自旋锁在用户空间转,PREEMPT_NONE 能让它尽量不受干扰地把活干完。

Linux 7.0 把这个选项砍了。现在只剩 PREEMPT_FULLPREEMPT_LAZY,调度器变得更”积极主动”。听起来是好事?但对于 PostgreSQL 来说,这意味着大量时间被浪费在等待锁释放而不是真正计算上。

引用 PostgreSQL 开发者社区的话来说:用户空间自旋锁的等待时间大幅增加,是性能下降的根本原因。

有意思的是,这个问题不只是 ARM64 平台。受影响的有 x86_64、PowerPC、RISC-V、s390、LoongArch——基本上 Linux 7.0 支持的主流架构全中了。

代价是什么?

算笔账就清楚了。

一家公司有 10 台跑 PostgreSQL 的 Graviton4 服务器,为了维持原有的查询吞吐量,现在需要 20 台。计算资源直接翻倍,成本也跟着翻倍。

而且这还不是终点。PostgreSQL 社区已经在讨论对策了,要求在不同条件下重复测试、等待 RSEQ(Restartable Sequences)支持的进一步明确。托管数据库服务如 AWS RDS 和 Google Cloud SQL,大概率会推迟采用 Linux 7.0——但对于自己管服务器的人来说,这个坑可能避不开。

普通人怎么办?

几点建议:

1. 生产环境先别升内核
如果你管着 PostgreSQL 数据库服务器,Linux 7.0 的升级计划先按住。尤其是跑在云服务器上的,等社区有了明确结论再说。

2. 把性能基准测试写进升级流程
很多团队升级内核就是 apt upgradeyum update 就完事了,根本不测数据库性能。从现在起,给内核升级配一套 pgbenchsysbench 测试流程,让数据库性能回归测试成为标配。

3. 盯紧关键指标
上线之后,关注内核版本号和 spinlock 等待时间这两个指标。如果等待时间突然往上跳,性能又明显下降,很可能就是踩到这个坑了。

4. x86_64 暂时别慌
目前实测数据集中在 Graviton4(ARM64),x86_64 的情况还有待更多社区反馈。但谁也不知道下一个爆的是哪个架构。

 


说实话,每次内核大版本发布,我都会捏把汗。内核是整个软件栈的地基,动一下波及面太大。这次 Linux 7.0 还在 RC 阶段(正式版预计 4 月 18 日),还有时间让社区找解法。

但有一点是确定的:生产环境的内核升级,再也不能裸升了。


参考资料:
AWS engineer report (linux.org thread)
Phoronix (linux.org thread)
Hacker News discussion (news.ycombinator.com)