##
紧急预警!Linux 7.0 强拆“关键开关”,PostgreSQL 性能直接腰斩?DBA 必须关注的底层巨变
摘要: 当 Linux 内核决定抛弃“老旧”的设计时,PostgreSQL 成了最受伤的对象。AWS 工程师的实测报告揭示了一个残酷的现实:内核的进步,有时竟是数据库的灾难。
正文:
作为 DBA,我们习惯了通过升级内核来获取性能红利,但这一次,情况完全反转了。
最近,在 Linux 社区和 Reddit 上引发轩然大波的一则消息(源自 AWS 工程师的报告):在最新的 Linux 开发分支中,PostgreSQL 的性能在某些高并发场景下暴跌了近 50%。 这不是一个小 Bug,而是一场关于操作系统底层调度模型与数据库架构的“世纪大碰撞”。
一、 祸起萧墙:被“裁掉”的 PREEMPT_NONE
这次性能崩塌的导火索是 Linux 内核计划在 7.0 版本(及相关演变中)彻底移除 CONFIG_PREEMPT_NONE。
在过去几十年里,DBA 在部署高性能数据库服务器时,通常会选择这种非抢占模式。它的逻辑很简单:让 CPU 尽可能长时间地处理当前任务,减少不必要的上下文切换,从而换取极限的吞吐量。
然而,内核开发者认为这种模式增加了维护成本,决定全面推行“抢占式”调度(尤其是引入了 PREEMPT_LAZY 机制)。这意味着:内核现在可以随时强行打断一个正在运行的进程。
二、 为什么 PostgreSQL “最受伤”?
为什么这次调整对 PostgreSQL 的伤害远比对其他软件大?这涉及到 PG 核心的锁机制——自旋锁(Spinlock)。
- 1. PG 的假设:PostgreSQL 在处理并发时,大量使用了轻量级的自旋锁。PG 开发者基于多年来的经验假设:“我持有锁的时间极短,内核通常不会在这个瞬间把我切走。”
- 2. 现实的重击:在新的内核调度下,PG 进程刚拿到自旋锁,内核可能就因为它“运行太久”或者有更高优先级的任务,强行将其挂起。
- 3. 连锁反应:锁持有者被挂起了,但锁还没释放!此时,服务器上几十个甚至上百个其他 CPU 核心都在疯狂“自旋”等待这个锁。
这就造成了 CPU 占用率满载(都在空转等待),但实际交易吞吐量(TPS)却直线坠落。AWS 工程师在 96 核的机器上观测到了极其显著的性能衰减——这种硬件配置越高,由于锁争用导致的“负优化”就越明显。
三、 DBA 的反思:谁的错?
在社区的讨论中,观点分成了两派:
- • 内核派:认为 PostgreSQL 的锁设计太“古老”了,过度依赖于内核的非抢占特性。他们建议 PG 应该改用
futex 或者其他更现代的同步原语。 - • 数据库派:认为 Linux 作为服务器操作系统,不应该为了桌面端的响应速度(UI流畅度)而牺牲数据库的吞吐量。既然 Linux 号称是企业级系统,就不该移除这种关键的性能开关。
事实上,这种冲突反映了现代计算环境的变迁:内核越来越倾向于低延迟(Latency),而数据库追求的是高吞吐(Throughput)。
四、 我们该怎么办?
虽然 Linux 7.0 距离生产环境的大规模应用还有一段距离,但作为 DBA,我们需要提前做好准备:
- 1. 关注内核启动参数:未来升级内核时,必须关注
preempt=none 这一类 Fallback 参数是否还生效。 - 2. PG 版本的进化:PostgreSQL 社区已经在紧急讨论如何优化自旋锁代码。未来的 PG 版本可能会引入“调度感知”的锁机制,但在那之前,老版本的 PG 运行在新内核上将面临巨大风险。
- 3. 灰度测试的重要性:千万不要直接在生产环境升级大版本内核。在多核(尤其是 64 核以上)服务器上,必须进行严苛的压力测试。
写在最后
这次“性能惨案”提醒我们:数据库从不是孤立存在的,它是构建在内核之上的精密机器。 当底层地基发生变动时,即便是一行微小的内核代码改动,也足以掀翻上层建筑。作为 DBA,我们不仅要懂 SQL 调优,更要时刻盯着内核演进的脚步。
今日互动: 你遇到过升级内核后性能反而下降的情况吗?欢迎在评论区分享你的避坑经验。
参考来源:Phoronix, Reddit /r/linux, AWS Performance Reports