我的工作表上有这种情况。
客户已经重启(至less2次)运行PostgreSQL的机器。 之后,一列上的下一个序列已经改变。
重启之前的最后一个值是582.重启后它应该返回583,而是返回615。
我已经检查了所有可能的日志,从Linux系统日志通过PostgreSQL日志,直到我们的应用程序日志,没有看到任何调用nextval在这一行。
所以我尝试了这个疯狂的想法,并把数字转换成了一些数字。
583 in bits: 0010 0100 0111 615 in bits: 0010 0110 0111
只有一个位的差异。 那么,是否有可能从硬重启中搞砸了?
在这个时候,这个名为33次的nextval真的没有多lessselect。 返回582的呼叫和返回615的呼叫之间的时间差只有一个小时左右,在那个时候PC重新启动了两次。 是的,编程已经很长时间了,但是在那段时间里再也没有调用nextval的意思了。
编辑#1:
我检查了cache_value
,它是1(因为它可能应该是)。 另外increment_by
也是1。 所以不应该有任何分配的值。 正在调用nextval
的代码连接到硬件开关(钱箱传感器),当激活时,它find钱箱状态并将其插入到id为该序列的表中。 在插入新行之前有一些相当繁重的select,所以如果被调用,我们的应用程序日志或PostgreSQL日志中会有一些脚印。
我之所以关心,是因为这个序列是用于兑现货币兑换日志的ID,所以ID中的差距看起来不太好,即使我们可以certificate这两个ID之间没有做任何事情。
有关如何在Postgres中生成序列的详细信息,请参阅此Postgres文档 。
引用文档:
因此,会话结束时分配但未在会话中使用的任何号码都将丢失,导致序列中出现“漏洞”。
这很可能是因为序列发生器有一些缓存的序列值,在硬重启过程中会丢失。 或者,正在进行的一个或多个事务已经检索到一个序列值,但在能够提交事务之前被中断。
有关序列生成的文档可能会帮助您确定如何设置序列高速缓存的大小以及“重新启动”的值。
另外:在你的情况下,听起来好像你可能有一个业务规则,要求你的表中的主键是连续的和无间隙的(序列之间没有间隙)。 A. Elein Mustain提出了产生所谓的“无间隙序列”的非平凡解决方案 。