OpenTeleDB基于PostgreSQL 17开发,新增三大特性:XProxy、XStore和XRaft。
OpenTeleDB新增的关键特性之一是 XStore,该特效通过Undo机制提供了原位更新能力:
XStore是针对高并发的OLTP场景、要求性能稳定的业务所设计的原位更新存储引擎。XStore通过重新设计堆表xheap、重新设计索引xbtree,每次数据更新时,直接在原位更新数据,旧数据写入Undo,从而解决了数据空间膨胀的问题。同时通过原位更新和回滚管理机制,自动vacuum不再需要扫盘回收数据页和索引页,彻底解决垃圾回收带来的性能波动。
在数据库的世界,修改数据存在两种主要方式,分别是原位更新和追加更新:
原位更新:是在原数据位置直接更新数据,旧数据另辟空间记录(以应对MVCC的需求),新开辟的空间被称为UNDO。Oracle采用原位更新,历史悠久。UNDO是Oracle创始人、技术天才Bob Miner的实现。
追加更新:在更新时新追加写入一条进的数据,原记录标记为历史版本。PostgreSQL采用追加更新机制。

这两种记录更有优缺点。Postgre领域的大神Tom Lane说:
我认为原地更新(update-in-place)相较于HOT更新,并没有给我们带来多少额外优势。若要实现多版本并发控制(MVCC)语义,就得在某处保留元组(tuple)的两个版本。Oracle的解决方案与我们不同,但我并不认为它更优。它确实改进了某些方面,却也恶化了其他方面。在Oracle中,所有事务都得在庞大的撤销日志(UNDO log)里搜寻所需信息。
zheap:这是 EnterpriseDB 开源的项目。EDB开发了一种被称为zheap的新的存储格式。在这种格式中,只有数据的最新版本保留在主存储中,而旧版本则被移动到撤销日志(Undo Log)中。zheap通过原位更新来避免表膨胀同时减小tuple headers。
Ustore:又名In-place Update存储引擎,是 openGauss 内核新增的一种存储模式。openGauss自2020年开源,最初使用的行存储引擎是Append Update(追加更新)模式。追加更新对于业务中的增、删以及HOT(Heap Only Tuple)Update表现佳,但对于跨数据页面的非HOT UPDATE场景,垃圾回收不够高效。因此,Ustore应运而生。

OrioleDB:MVCC基于UNDO日志实现。旧版本的元组放逐到undo链的undo日志中,避免主存储系统膨胀。页级别的undo记录允许系统很方便地尽快回收已删除元组占用的空间。大多数情况下,这些机制与page-mergins一起消除了膨胀。OrioleDB在2024年被Supabase收购。

XStore:XStore是天翼云设计的原位更新存储引擎。XStore通过重新设计堆表xheap、重新设计索引xbtree,每次数据更新时,直接在原位更新数据,旧数据写入Undo。
很难想象,对于开源社区实现一项新功能也是争议重重。MySQL早年在存储引擎上也遇到过巨大的挑战,采用UNDO机制的InnoDB作为其最佳存储引擎被Oracle收购,随后MySQL也辗转被Oracle持有。在MySQL的世界里,InnoDB 和Oracle的行为越来越趋同。
Undo对于数据库来说,是一个非常复杂的功能,影响到最核心的事务处理,所以多年以来Postgres社区对于Undo的采纳非常谨慎。此外,Postgres社区从进程模式到线程模式的改造也仍处于进程中,并充满争议。
社区保持谨慎,但是勇敢者不断尝试。看到这么多人在反复重构Ustore,一次又一次的重复造轮子,相信Postgres社区早晚会有回响。
在Postgres的世界里,各种企业版本都将 Undo 作为其核心特性,Undo 已经成为PG的最后一个执念。

