目录结构
注:提前言明 本文借鉴了以下博主、书籍或网站的内容,其列表如下:
1、参考书籍:《PostgreSQL数据库内核分析》
2、参考书籍:《数据库事务处理的艺术:事务管理与并发控制》
3、PostgreSQL数据库仓库链接,点击前往
4、日本著名PostgreSQL数据库专家 铃木启修 网站主页,点击前往
5、参考书籍:《PostgreSQL中文手册》
6、参考书籍:《PostgreSQL指南:内幕探索》,点击前往
7、参考书籍:《事务处理 概念与技术》
8、PostgreSQL: No More VACUUM, No More Bloat,点击前往
1、本文内容全部来源于开源社区 GitHub和以上博主的贡献,本文也免费开源(可能会存在问题,评论区等待大佬们的指正)
2、本文目的:开源共享 抛砖引玉 一起学习
3、本文不提供任何资源 不存在任何交易 与任何组织和机构无关
4、大家可以根据需要自行 复制粘贴以及作为其他个人用途,但是不允许转载 不允许商用 (写作不易,还请见谅 💖)
5、本文内容基于PostgreSQL 16.1源码开发而成
PostgreSQL:不再有 VACUUM,不再有臃肿
- 文章快速说明索引
- 功能使用背景说明
- 原文评论内容精选
- 相关内容链接展示

文章快速说明索引
学习目标:
做数据库内核开发久了就会有一种 少年得志,年少轻狂 的错觉,然鹅细细一品觉得自己其实不算特别优秀 远远没有达到自己想要的。也许光鲜的表面掩盖了空洞的内在,每每想到于此,皆有夜半临渊如履薄冰之感。为了睡上几个踏实觉,即日起 暂缓其他基于PostgreSQL数据库的兼容功能开发,近段时间 将着重于学习分享Postgres的基础知识和实践内幕。
学习内容:(详见目录)
1、PostgreSQL:不再有 VACUUM,不再有臃肿
学习时间:
2024-03-08 22:38:19 星期五
学习产出:
1、PostgreSQL数据库基础知识回顾 1个
2、技术博客 1篇
3、PostgreSQL数据库内核深入学习
注:下面我们所有的学习环境是Centos8+PostgreSQL16.1+Oracle19C+MySQL8.0
postgres=# select version();version
------------------------------------------------------------------------------------------------------------PostgreSQL 17devel on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-21), 64-bit
(1 row)postgres=##-----------------------------------------------------------------------------#SQL> select * from v$version; BANNER Oracle Database 19c EE Extreme Perf Release 19.0.0.0.0 - Production
BANNER_FULL Oracle Database 19c EE Extreme Perf Release 19.0.0.0.0 - Production Version 19.17.0.0.0
BANNER_LEGACY Oracle Database 19c EE Extreme Perf Release 19.0.0.0.0 - Production
CON_ID 0#-----------------------------------------------------------------------------#mysql> select version();
+-----------+
| version() |
+-----------+
| 8.0.27 |
+-----------+
1 row in set (0.06 sec)mysql>
功能使用背景说明
PostgreSQL 是一个功能强大的开源对象关系数据库系统,因其稳健性、功能性和灵活性而备受赞誉。然而,它并非没有挑战——其中之一就是"臭名昭著"的 VACUUM 过程。然而,新时代的黎明已经来临,OrioleDB 是一种专为 PostgreSQL 设计的新颖引擎,有望消除对资源消耗型 VACUUM 的需求。
PostgreSQL 中 VACUUM 的可怕故事
PostgreSQL 中的 VACUUM 进程是一个历史产物,其根源可以追溯到 Berkeley Postgres 项目,该项目实现了一个称为无限时间旅行的概念。这个概念虽然在当时具有创新性,但最终被 PostgreSQL 社区放弃。然而,它导致了多版本并发控制(MVCC)系统的实现容易出现表膨胀。
PostgreSQL MVCC 系统虽然有利于处理并发事务,但也引入了手动清理的需求。这是一个清除旧的、不需要的数据以释放空间并确保高效的数据库操作的过程。然而,手动清理是一项劳动密集型任务,也是系统效率低下的潜在根源。
PostgreSQL 社区在不断努力改进系统的过程中,引入了 autovacuum - 一种自动清理过程,旨在减轻手动清理的需要。这是向前迈出的重要一步,但并不是一个完美的解决方案。autovacuum 过程虽然是自动的,但仍然消耗大量的系统资源。这是 Uber 决定从 PostgreSQL 迁移到 MySQL 的原因之一,也是 Richard Branson 讨厌 PostgreSQL 的 10 件事之一。
随着堆元组 (HOT) 更新和 microvacuum 的实施,进一步增强了功能,这两项重大改进都减少了对全表真空的需求。然而,尽管取得了这些进步,VACUUM 过程仍然是一个资源密集型操作。此外,PostgreSQL 表仍然容易膨胀,这个问题至今仍然困扰着许多用户。这是 OtterTune 团队最讨厌的 PostgreSQL 部分。
尽管面临这些挑战,许多组织和开发人员仍然继续使用和支持 PostgreSQL。它的稳健性、可扩展性和强大的社区只是其中的几个原因。例如,OtterTune 尽管承认 PostgreSQL 的问题,但仍决定坚持使用它。他们在另一篇博客文章中解释了他们的原因,强调了在做出决定之前考虑系统整体优点和缺点的重要性。
OrioleDB 登场:未来的引擎
OrioleDB 是 PostgreSQL 的一个突破性的新引擎,其开发的主要目标是:避免表膨胀并消除像 VACUUM 这样的定期维护的需要。它通过实现行级和块级撤消日志以及自动页面合并来实现这一点。
行和块级别的撤消日志提供更精细的控制级别,从而可以更有效地处理数据更改。自动页面合并功能在后台不知疲倦地工作,整合碎片数据,进一步提高系统的效率。
上图说明了这种技术。行级撤消日志允许就地更新。块级撤消日志允许从主存储中逐出已删除但对某些事务可见的元组,为新元组留下更多空间。稀疏页面的自动合并可以避免表和索引在多次删除后出现膨胀。
OrioleDB 中这些功能的实现使得系统需要更少的手动干预,消耗更少的资源,并且不易出现表膨胀。这有望显着提高 PostgreSQL 的性能和用户体验。
基准测试
以下综合基准测试可以说明 OrioleDB 的上述优点以及其他一些优点。 以下初始化脚本创建一个表并在其上创建 5 个索引。
CREATE TABLE test (id integer primary key,value1 float8 not null,value2 float8 not null,value3 float8 not null,value4 float8 not null,ts timestamp not null
);CREATE INDEX test_value1_idx ON test (value1);
CREATE INDEX test_value2_idx ON test (value2);
CREATE INDEX test_value3_idx ON test (value3);
CREATE INDEX test_value4_idx ON test (value4);
CREATE INDEX test_ts_idx ON test (ts);
下面给出了 pgbench 脚本。这是一种更新插入,在发生冲突时对索引之一执行稀疏更新。使用常规 PostgreSQL 堆表时,稀疏更新会导致该索引膨胀。
\set id random(1, 10000000)INSERT INTO test VALUES(:id, random(), random(), random(), random(), now() - random() * random() * 1800 * interval '1 second')
ON CONFLICT (id) DO UPDATE SET ts = now();
该基准测试说明了 OrioleDB 设计的以下优点。
- 得益于撤消日志和就地更新,OrioleDB 只需要更新一个索引,该索引的值已更改。 使用 PostgreSQL 堆引擎,单个索引字段的更新会禁用 HOT,因此所有索引都会更新。
- 自动页面合并可防止稀疏索引膨胀。 稀疏页面会自动合并。
- 行级 WAL 比块级 WAL 占用的空间少得多。 这可以节省 WAL 写入的 IOPS。
实验在c5d.18xlarge机器上进行,并发连接数为100。 请参阅下图中的基准测试结果。
作为上述改进的累积结果,OrioleDB 提供了:
- TPS 提高 5 倍,
- 每个事务的 CPU 负载减少 2.3 倍,
- 每个事务的 IOPS 减少 22 倍,
- 没有表和索引膨胀。
拥抱未来:立即尝试 OrioleDB
随着 OrioleDB 的推出,PostgreSQL 社区正处于一个新时代的边缘,VACUUM 的困扰已成为过去。 这个新颖的引擎为 PostgreSQL 长期存在的挑战之一提供了引人注目的解决方案,承诺用户提高效率并减少维护麻烦。
原文评论内容精选
Q:你考虑过LMDB吗? 您是否对其性能和设计进行了权衡比较?
A:LMDB(和 MDBX)非常酷。LMDB 和 OrioleDB 具有共同的高级概念(写时复制 B 树)。然而,LMDB 是一个嵌入式数据库,它允许单个写入器和多个读取器。OrioleDB 是为 PostgreSQL 设计的,它允许多个写入器和读取器同时工作。由于单写者限制,LMDB 可以使用写时复制来实现事务原子性和 MVCC。OrioleDB 必须实现更复杂的解决方案,包括撤消日志和棘手的检查点算法。我喜欢 LMDB,但从未考虑将其改编为 PostgreSQL,因为它们属于不同类别的系统。
Q:是否希望将其集成到 PostgreSQL 中,使其成为默认的标准引擎?
A:是的,当然! 但这还有很长的路要走。目前 OrioleDB 是一个扩展,附带 PostgreSQL 核心补丁。OrioleDB 的中期目标是成为一个纯粹的扩展。长期目标是使 OrioleDB 成为 PostgreSQL 核心的一部分。现实的雄心勃勃的计划是将最重要的补丁提交给 PG17,并在 PG18 中成为纯粹的扩展。
相关内容链接展示
- OrioleDB – the next generation storage engine for PostgreSQL
- 官方git仓库
- Для PostgreSQL представлен движок хранения OrioleDB, обходящийся без операции VACUUM