【问题标题】:What does log_cnt mean in the postgres sequence?postgres 序列中的 log_cnt 是什么意思?
【发布时间】:2026-01-27 10:35:01
【问题描述】:

我试图弄清楚为什么我的表中的序列号呈指数级增长,而这可能是我的 API 中的一个问题,我仍然需要弄清楚,我遇到了这个查询 找到序列的当前值 SELECT * from some_sequence

它给了我一个名为log_cnt 的列。该列的值一直在 30 左右跳跃。我不确定这个数字是什么意思,以及这是否会影响序列中的下一个数字。

有人可以帮我解决这个问题吗?

【问题讨论】:

  • 如果序列值在跳跃,或者某人/事物直接改变了last_value,或者有很多失败的插入正在用完数字而没有出现在表格中。
  • 您的序列是否为缓存设置了 >1 的值?
  • 实际上是插入失败导致数字跳跃。感谢您的输入@AdrianKlaver
  • @jjanes 我不知道如何检查。但如果这是默认设置,那么我肯定没有更改此设置。
  • 查找缓存大小select * from pg_sequence where seqrelid = 'some_seq'::regclass;更多信息pg_sequence

标签: postgresql sequence


【解决方案1】:

必须将序列状态的更改写入事务日志 (WAL)。 这可能会导致大量 WAL 记录,从而损害性能。

作为一种优化,PostgreSQL 不会记录当前的序列计数器,而是记录一个大 32 的值。请参阅src/backend/commands/sequence.c 中的此评论:

/*
 * We don't want to log each fetching of a value from a sequence,
 * so we pre-log a few fetches in advance. In the event of
 * crash we can lose (skip over) as many values as we pre-logged.
 */
#define SEQ_LOG_VALS    32

这意味着在崩溃期间最多可能会丢失 32 个序列值(恢复会将序列设置为记录的位置),这没有问题。

log_cnt 显示在必须写入新的 WAL 记录之前剩余的提取次数。

在一个检查点后第一次调用nextval后,log_cnt将为32。每调用一次nextval,它就会减少,一旦达到0,它就会再次设置为32,并且是一条WAL记录写好了。

【讨论】: