OrioleDB 来了!4x性能,消除顽疾,存算分离

OrioleDB 奥利奥数据库,这名字听着很有趣,不过 Oriole 是黄鹂的意思,所以其实中文译名应该是 “黄鹂数据库”。 叫饼干DB还是小鸟DB都不重要,重要的是这个 PG 存储引擎扩展 + 内核分支确实很有趣,而且基本上快要正式发布了。

作为 zheap 的后继,我关注 OrioleDB 已经很久了,它的主要亮点有三个:性能,运维,云原生。 那么今天简单介绍一下这个 PG 内核新秀,以及最近我做的一些工作,可以让用户直接把它跑起来。


极致性能,四倍吞吐

虽然说在当下对于 OLTP 数据库来说,在绝大多数场景下,硬件性能已经严重过剩,不过单一业务单机 写入吞吐量 成为瓶颈的情况也并不算罕见,这也是大家去做 “分库” 的主要原因。

OrioleDB 旨在解决这个问题,根据它们官网首页的宣称,他们的读 / 写吞吐可以达到 PostgreSQL 的四倍,老实说这是一个相当惊人的数字 —— 40% 的性能提升不足以成为使用一个新存储引擎的理由,但 400% 确实可以成为一个不错的理由了。

bench.png

而且,OrioleDB 还声称显著减少了 OLTP 场景下的资源消耗,显著降低磁盘的 IOPS 读写使用率。

当然这里有一些相对于 PG 堆表的关键优化,比如去掉了 FS Cache,内存页面直接链接到存储页面,内存页面可以无锁访问,另外使用 UNDO 日志/回滚段来实现 MVCC 而不是 PG 的 REDO,还有易于并行化的行级 WAL。

老实说我还没有自己测过性能。但听上去很有诱惑,最近要是有空我会找台服务器试一试。


消除顽疾,简化运维

PostgreSQL 中最 “臭名昭著” 的问题莫过于 XID Wraparound,另一个让人 “心烦” 的问题则是表膨胀,而这两个问题都源于 PostgreSQL 的 MVCC 设计。

PostgreSQL 的默认存储引擎在设计的时候,想要实现一个 “无限时间旅行” 的概念,因此使用了一个追加写入的 MVCC 设计 —— DELETE 是标记删除,而 UPDATE 是标记删除并创建一个新版本。

这样的设计虽然带来了一些好处,比如读写相互不阻塞,事务多大都无所谓并可以瞬间回滚,且不会产生海量复制延迟,但也确实在另一个角度给 PostgreSQL 用户带来了额外的烦恼 —— 尽管在现代硬件上,尽管已经有了自动垃圾回收,但一套高标准的 PostgreSQL 数据库服务仍然要不时操心膨胀与垃圾回收的问题。

OrioleDB 旨在通过一款新的存储引擎解决这个问题 —— 可以粗略理解为,它使用类似 Oracle / MySQL 的存储引擎方案,同时继承了 O/M 的优缺点。比如,因为使用了新的 MVCC 实践,OrioleDB 存储引擎的表不会再有膨胀与 XID 回卷的概念了。

当然,有得必有失,这样设计当然也会继承这样设计的缺点,比如大事务问题,回滚慢问题,分析性能问题。但它的好处是可以把海量 OLTP CRUD 这个单一场景的性能做到极致。

而且最重要的是,这是一个 PG 的扩展,一个可选的存储引擎,和原本的 PG 堆表并不是互斥的选项,使用 OrioleDB 的同时,并不妨碍你同时继续使用 PG 原生的存储。这样你就可以根据具体的场景进行最佳利弊权衡,让那些需要极致 OLTP 性能与可靠性的表发挥其最大潜能。

-- 启用 OrioleDB 扩展(Pigsty 已经提供)
CREATE EXTENSION orioledb;

CREATE TABLE blog_post
(
  id int8 NOT NULL,
  title text NOT NULL,
  body text NOT NULL,
  PRIMARY KEY(id)
) USING orioledb; -- 使用 OrioleDB 存储引擎

使用 OrioleDB 非常容易,建表带 USING 关键词就可以了。

目前 OrioleDB 是一个存储引擎 PG 扩展插件,不过因为一些存储引擎需要的 API 补丁还没有进入 PG 主干,所以目前需要一个打过补丁的 PG 内核才可以运行,如果顺利,在 PostgreSQL 18 这些补丁合入主干就不再需要魔改内核了。

Name Link Version
✅ Add missing inequality searches to rbtree Link PostgreSQL 16
✅ Document the ability to specify TableAM for pgbench Link PostgreSQL 16
✅ Remove Tuplesortstate.copytup function Link PostgreSQL 16
✅ Add new Tuplesortstate.removeabbrev function Link PostgreSQL 16
✅ Put abbreviation logic into puttuple_common() Link PostgreSQL 16
✅ Move memory management away from writetup() and tuplesort_put*() Link PostgreSQL 16
✅ Split TuplesortPublic from Tuplesortstate Link PostgreSQL 16
✅ Split tuplesortvariants.c from tuplesort.c Link PostgreSQL 16
✅ Fix typo in comment for writetuple() function Link PostgreSQL 16
✅ Support for custom slots in the custom executor nodes Link PostgreSQL 16
✉️ Allow table AM to store complex data structures in rd_amcache Link PostgreSQL 18
✉️ Allow table AM tuple_insert() method to return the different slot Link PostgreSQL 18
✉️ Add TupleTableSlotOps.is_current_xact_tuple() method Link PostgreSQL 18
✉️ Allow locking updated tuples in tuple_update() and tuple_delete() Link PostgreSQL 18
✉️ Add EvalPlanQual delete returning isolation test Link PostgreSQL 18
✉️ Generalize relation analyze in table AM interface Link PostgreSQL 18
✉️ Custom reloptions for table AM Link PostgreSQL 18
✉️ Let table AM insertion methods control index insertion Link PostgreSQL 18

我在 EL 上做好了 oriolepg_17 的补丁版 PG,以及 orioledb_17 的扩展插件,并且提供了一个开箱即用的配置模板,可以一键拉起 OrioleDB 尝鲜。


云原生存储

“云原生”这个词已经被用滥了,没有人具体知道它到底在说啥。但对于数据库来说,云原生通常意味着 —— 把数据放在对象存储上。

OrioleDB 最近把自己的 Slogan 从 “高性能 OLTP 存储引擎” 修改为 “云原生存储引擎”,算是某种程度上的 Pivoting。我能理解这背后的原因 —— Supabase 把 OrioleDB 收购了,金主爸爸的需求总是第一位的。

orioledb-join-supabase.png

Oriole joins Supabase

作为一个 “云数据库服务商”,把用户的冷数据丢到 “廉价” 的对象存储 而不是 天价的 “EBS” 云盘块存储,显然是十分有利可图的一件事,而且这样可以让数据库变为无状态的“牲畜”,放在 K8S里随意销毁创建扩缩容。因此我完全能理解他们的动机。

所以当 OrioleDB 除了提供一种新的存储引擎之外,甚至还支持把数据放到对象存储上时,我是蛮高兴的。PG over s3 的项目并不是没有,但一个足够成熟,不脱离主干,还开源的这确实是第一个。

OrioleDB Docs: Decoupled storage and compute


所以,我想试试,咋整?

当然,OrioleDB 听上去非常美好,解决了 PG 的几个关键问题,(未来)兼容PG主干,还开源免费,也有金主投钱持续维护,创始人 Alexander Korotkov 也在 PG 开发者社区中有显著的贡献与声望。

但显然,现在 OrioleDB 还没有 “生产 Ready” ,我从三年前看着它发布第一个 Alpha1 版本,到现在也才是 Beta10,每次发布看的我都快麻了。但是最近我敏锐的注意到,它已经进入到 Supabase 的 postgres 镜像主干了,这意味着它离正式发布不远了。

所以呢,在 4月1 号 OrioleDB 发布最新的 beta10 的时候,我准备把它收录进来。正好刚做完 OpenHalo 的 RPM 包,都已经打包一个 MySQL 兼容的 PG 内核了,也不差再加双筷子,我就制作了补丁版 PG 内核 oriolepg_17 ,以及扩展插件 orioledb_17 的 RPM 包,在 EL8 / EL9 ,x86 / ARM64 上可用。

更重要的是,我在 Pigsty 中添加了 对 OrioleDB 的原生支持,这意味着 OrioleDB 也可以享受到 PG 生态组件的完整合力 —— 你可以使用 Patroni 做 HA,使用 pgBackRest 做备份,pg_exporter 做监控,pgbouncer 做链接池,而 Pigsty 替你将所有这些串成可以一键拉起的生产级 RDS 服务:

在清明节,我刚发布了 Pigsty v3.4.1 ,已经内置了对 OrioleDB 和 OpenHalo 内核的支持,想要拉 OrioleDB 内核,和拉起普通 PostgreSQL 数据库集群也并没有多少区别:

all:
  children:
    pg-orio:
      vars:
        pg_databases:
        - {name: meta ,extensions: [orioledb]}
  vars:
    pg_mode: oriole
    pg_version: 17
    pg_packages: [ orioledb, pgsql-common  ]
    pg_libs: 'orioledb.so, pg_stat_statements, auto_explain'
    repo_extra_packages: [ orioledb ]

还有其他内核花活

当然,这里支持的 PG 分支内核可不止 OrioleDB 一个,你还可以使用:

  • 兼容微软 SQL Server 的 Babelfish(由 AWS 出品)
  • 兼容 Oracle 的 IvorySQL(由瀚高出品)
  • 兼容 MySQL 的 openHalo(由易景科技出品)
  • Aurora RAC 风味的 PolarDB(由阿里云出品)
  • 正儿八经带有国产信创资质,Oracle 兼容的 PolarDB O 2.0。
  • 你还可以用 FerretDB + 微软出品的 DocumentDB 将 PG 仿真为一个 MongoDB。
  • 使用 Pigsty 自建模板一键拉起本地的 Supabase (OrioleDB 它爹!)。

另外,我的朋友 Yurii ,Omnigres 的创始人正在给 PostgreSQL 套上 ETCD 协议支持, 估计不远的将来,你还可以把 PG 当成一个性能/可靠性更好的 etcd 给 Kubernetes / Patroni 去使用。

kernels.png

最重要的是,所有这些能力都是开源的,而且已经全部在 Pigsty 中免费的开箱即用了。 所以,如果你想体验一把 OrioleDB,不妨找台服务器试试,一键安装,10分钟搞定。 看看是不是真像他们说的那么牛逼。




最后修改 2025-04-09: add two new blog (76cf63b)