数据库世界正在发生一场微妙但深刻的变革。过去,传统数据库的竞争焦点是 SQL 功能、事务能力和高可用;如今,越来越多公司开始争夺存储引擎本身的制高点。因为当应用层开发趋同以后,真正决定系统天花板的不再是 API 或者加几个缓存节点,而是数据如何被写入、排列、索引和复制。Supabase 最近为 OrioleDB 招聘的消息,就是这种趋势的最新注脚。作为 Y Combinator 2020 年夏季营走出的开源明星,Supabase 从一开始就不满足于只做 Firebase 的替代品,它要做的,是把整个开源数据库世界的底层体验握在自己手里。 如果你关注过 Supabase 的成长轨迹,一定知道这家公司有一个非常鲜明的立场:一切围绕 PostgreSQL。
别的团队可能会为了性能和成本去研发一堆新数据库,Supabase 却选择把注押在一个已经有三十多年历史的开源数据库上,然后再用现代云原生的方式重写它。这样做的优势很明显,因为 PostgreSQL 早已成为全球开发者的默认选择之一,生态里充满了成熟的数据类型、索引方法、扩展机制和丰富的社区知识。Supabase 要做的,不是发明一个新数据库让用户再学一遍,而是让用户在不离开 SQL 的前提下,获得毫不妥协的性能。现在,聘请核心数据库工程师去完善 OrioleDB,是这一步最关键的投资。 那么 OrioleDB 到底是什么?简单来说,它是一套为 PostgreSQL 设计的新一代存储引擎,目的不是修修补补,而是从数据文件的组织方式上彻底改变 Postgres 处理写入、更新、索引和恢复的方式。熟悉数据库底层的人知道,PostgreSQL 自带的堆表结构虽然功能强大,但在高并发更新和长时间运行的高负载场景下,容易出现膨胀、写放大和后台清理压力。
传统解决方法是升级硬件、分库分表,或者引入中间层缓存,但这些都没有解决本质问题。OrioleDB 的思路,是利用 PostgreSQL 从 12 版本开始提供的可插拔存储表访问接口,直接替换掉默认的存储布局。具体来看,它把数据行和索引以一种更适合现代磁盘和内存的行为组织在一起,让常用索引扫描的数据更容易被 CPU 的缓存命中。更关键的是,OrioleDB 设计了一种全新的多版本并发控制实现方式。发布过的技术博客里提到,它使用 undo log 来管理行级版本,不再像堆表那样每次更新都生成一份新的死元组,再等着 vacuum 去清理。这一变化具有长尾效应,因为后台清理一旦减轻,数据库的延迟就变得更可预测,磁盘空间也不会突然被长事务吃满。
如果只是存储结构上的小修,OrioleDB 还不至于让整个数据库圈如此兴奋。真正有想象力的是它对写放大问题的重新思考。在传统 PostgreSQL 里,一个 UPDATE 操作不仅修改数据页本身,还会同时产生写前日志、更新索引、维护可见性信息;如果有备份恢复和级联复制,磁盘写入的总量会进一步上升。OrioleDB 通过改进预写日志的数据格式,减少冗余信息,让每个事务提交需要落盘的操作尽可能精简,同时配合更紧凑的数据页和更大粒度的批量更新机制,使系统在高并发下保持稳定的吞吐。这些能力对云数据库的意义尤其大,因为云平台上的用户是按 CPU、内存、磁盘 I/O 计费的,存储引擎一旦把写放大从十倍降到两倍,用户就能以相同的成本获得数倍的性能提升,这对 Supabase 本身的业务模式也有直接价值。 除了性能,OrioleDB 还在索引方面做了大量工作。
大多数数据库的索引都依赖 B 树,但 B 树在高并发随机插入时往往会造成页面分裂,让空间碎片化。OrioleDB 并不是宣称彻底抛弃 B 树,而是把索引的存储和主表的存储看成一个整体去调度。当插入操作发生时,系统先写到一个内存结构里,积累到一定阈值再合并到磁盘上的大块区域,这种方式减少了随机写入操作。更妙的是,这些变化全部隐藏在 PostgreSQL 的扩展接口背后。应用层开发者不需要修改任何 SQL 语句,也不需要改变连接池方式,只要在创建表的时候把表指定为 OrioleDB 的访问方法,就能享受到新存储引擎带来的好处。这种兼容性对开源软件来说极其重要,很多新技术之所以难以落地,就是因为升级成本太高,而 OrioleDB 选择了最平滑的切入路径。
Supabase 之所以愿意在这个时间点投入巨资招聘人才,而不是坐等存储引擎自己成熟,和开发者需求的变化有很大关系。过去几年,实时应用已经成了现代互联网产品 。