关于PostgreSQL序列的实现细节

时间:2019-01-15 14:14:52

标签: postgresql database-sequence

我对PostgreSQL中序列的实现细节感兴趣,原因是序列在SERIAL类型的背景中使用。我还检查了源文件here(可在Google搜索中找到:“ postgresql源代码序列”),尽管尚不清楚该文件与哪个版本的PG相关。我了解函数nextval_internal中的一般代码流程,这是问题的核心,但是PG的代码库很大,我只是没有时间花充分的时间研究此问题。

我想知道:

  • 关于序列的持久性策略是什么? PG服务器启动时如何加载它们?如何在服务器的生命周期内持久保存它们,以防止服务器崩溃/电源故障后发生事故?
  • 与使用序列相关联的运行时成本是多少?它们是否总是发生某种磁盘I / O,或者根本不发生?
  • 在定义表和编写应用程序代码时,应注意使用序列的哪些不足?

1 个答案:

答案 0 :(得分:2)

序列在许多方面都与普通表类似:它们在pg_class目录中找到,并且具有一个数据文件,该文件用于存储当前值。

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

持久性就像在普通表中一样进行事务处理(即使nextval不是事务性的),因此更改将通过事务日志进行,但是与普通表不同的是,没有多版本化。而是,序列的单行“就地”更改。可以,因为我们不需要使用其他版本的值,并且VACUUM将永远无法跟上忙碌清理的步伐。

要单独回答您的问题:

  • 在恢复过程中,与任何其他数据更改一样,将从WAL中重放对序列的更改。

  • 使用序列的开销很小。修改不会一直引起I / O,因为序列像所有其他表一样被缓存在共享缓冲区中。仅在检查点期间,它们才必须保留到存储中,并且要考虑少量的WAL。

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

  • 使用序列没有问题。它们是生成唯一数字的最佳方法。