关于PostgreSQL序列的实现细节

About the implementation details of PostgreSQL sequence

我对 PostgreSQL 中序列的实现细节很感兴趣,原因是它们在后台用于 SERIAL 类型。我查看了源文件 here(在 Google 搜索:"postgresql source code sequence" 中找到),虽然不清楚该文件与哪个版本的 PG 相关。我了解函数中的一般代码流程nextval_internal,这是问题的核心,但是PG的代码库很大,我没有时间去研究这个问题。

我有兴趣知道:

序列在很多方面都像普通的 table:它们位于 pg_class 目录中,并且有一个数据文件,存储当前值。

在最新版本的 PostgreSQL 中(作为使 ALTER SEQUENCE 完全事务化的副作用),您还必须 SELECT 从序列中查看其当前值。

持久性像在正常 table 中一样以事务方式处理(即使 nextval 不是 事务),因此更改会通过事务日志,但是与正常的 tables 不同,没有多版本控制。相反,序列的单行被“就地”更改。没关系,因为我们不需要不同版本的值,而且 VACUUM 永远无法跟上繁忙序列中的清理工作。

单独回答您的问题:

  • 在恢复期间,对序列的更改会像任何其他数据更改一样从 WAL 重放。

  • 使用序列的开销很小。修改不会一直导致 I/O,因为序列像所有其他 table 一样缓存在共享缓冲区中。仅在检查点期间,它们必须持久存储,并且需要考虑一些少量的 WAL。

    如果您想进一步减少使用序列的开销,请使用大于 1 的 CACHE 定义它们。

  • 使用序列没有问题。它们是生成唯一编号的最佳方式。