关于PostgreSQL序列的实现细节
About the implementation details of PostgreSQL sequence
我对 PostgreSQL 中序列的实现细节很感兴趣,原因是它们在后台用于 SERIAL
类型。我查看了源文件 here(在 Google 搜索:"postgresql source code sequence" 中找到),虽然不清楚该文件与哪个版本的 PG 相关。我了解函数中的一般代码流程nextval_internal
,这是问题的核心,但是PG的代码库很大,我没有时间去研究这个问题。
我有兴趣知道:
- 关于序列的持久性策略是什么?它们在 PG 服务器启动时如何加载,以及它们如何在服务器的生命周期内持久存在以防止服务器 crash/power 故障后发生意外?
- 与使用序列相关的运行时成本是多少?他们 总是 招致某种磁盘 I/O 还是从不招致?
- 在定义表和编写应用程序代码时,使用序列有哪些不足之处?
序列在很多方面都像普通的 table:它们位于 pg_class
目录中,并且有一个数据文件,存储当前值。
在最新版本的 PostgreSQL 中(作为使 ALTER SEQUENCE
完全事务化的副作用),您还必须 SELECT
从序列中查看其当前值。
持久性像在正常 table 中一样以事务方式处理(即使 nextval
是 不是 事务),因此更改会通过事务日志,但是与正常的 tables 不同,没有多版本控制。相反,序列的单行被“就地”更改。没关系,因为我们不需要不同版本的值,而且 VACUUM
永远无法跟上繁忙序列中的清理工作。
单独回答您的问题:
在恢复期间,对序列的更改会像任何其他数据更改一样从 WAL 重放。
使用序列的开销很小。修改不会一直导致 I/O,因为序列像所有其他 table 一样缓存在共享缓冲区中。仅在检查点期间,它们必须持久存储,并且需要考虑一些少量的 WAL。
如果您想进一步减少使用序列的开销,请使用大于 1 的 CACHE
定义它们。
使用序列没有问题。它们是生成唯一编号的最佳方式。
我对 PostgreSQL 中序列的实现细节很感兴趣,原因是它们在后台用于 SERIAL
类型。我查看了源文件 here(在 Google 搜索:"postgresql source code sequence" 中找到),虽然不清楚该文件与哪个版本的 PG 相关。我了解函数中的一般代码流程nextval_internal
,这是问题的核心,但是PG的代码库很大,我没有时间去研究这个问题。
我有兴趣知道:
- 关于序列的持久性策略是什么?它们在 PG 服务器启动时如何加载,以及它们如何在服务器的生命周期内持久存在以防止服务器 crash/power 故障后发生意外?
- 与使用序列相关的运行时成本是多少?他们 总是 招致某种磁盘 I/O 还是从不招致?
- 在定义表和编写应用程序代码时,使用序列有哪些不足之处?
序列在很多方面都像普通的 table:它们位于 pg_class
目录中,并且有一个数据文件,存储当前值。
在最新版本的 PostgreSQL 中(作为使 ALTER SEQUENCE
完全事务化的副作用),您还必须 SELECT
从序列中查看其当前值。
持久性像在正常 table 中一样以事务方式处理(即使 nextval
是 不是 事务),因此更改会通过事务日志,但是与正常的 tables 不同,没有多版本控制。相反,序列的单行被“就地”更改。没关系,因为我们不需要不同版本的值,而且 VACUUM
永远无法跟上繁忙序列中的清理工作。
单独回答您的问题:
在恢复期间,对序列的更改会像任何其他数据更改一样从 WAL 重放。
使用序列的开销很小。修改不会一直导致 I/O,因为序列像所有其他 table 一样缓存在共享缓冲区中。仅在检查点期间,它们必须持久存储,并且需要考虑一些少量的 WAL。
如果您想进一步减少使用序列的开销,请使用大于 1 的
CACHE
定义它们。使用序列没有问题。它们是生成唯一编号的最佳方式。