postgres序列字段中缺少值

时间:2010-08-04 09:33:19

标签: postgresql primary-key auto-increment

我运行一个小型站点并使用PostgreSQL 8.2.17(仅在我的主机上可用的版本)来存储数据。 在过去几个月中,我的服务器上发生了3次数据库系统崩溃,每次发生故障时,其中一个表中的串行字段(主键)发生了31个ID。现在有93个ID缺失。

表:

CREATE TABLE "REGISTRY"
(
  "ID" serial NOT NULL,
  "strUID" character varying(11),
  "strXml" text,
  "intStatus" integer,
  "strUIDOrg" character varying(11),
)

对我来说,所有ID值都在那里非常重要。我该怎么做才能解决这个问题?

3 个答案:

答案 0 :(得分:2)

你不能指望串行列没有漏洞。

你可以通过牺牲这样的并发来实现无间隙密钥:

create table registry_last_id (value int not null);
insert into registry_last_id values (-1);

create function next_registry_id() returns int language sql volatile
as $$
    update registry_last_id set value=value+1 returning value
$$;

create table registry ( id int primary key default next_registry_id(), ... )

但是任何尝试向registry表插入内容的事务都将阻塞,直到其他插入事务完成并将其数据写入磁盘。这将限制您在7500rpm磁盘驱动器上每秒不超过125个插入事务。

同样,从registry表中删除任何内容都会产生差距。

此解决方案基于A. Elein Mustain的文章Gapless Sequences for Primary Keys,这有点过时。

答案 1 :(得分:1)

您是否缺少93条记录,或者您有31个缺失数字的3个“漏洞”?

序列不是事务安全的,它永远不会回滚。因此,不是一个系统来创建一个数字序列没有孔。

来自manual

  

重要提示:避免阻塞   获得的并发事务   来自相同序列的数字,a   nextval操作永远不会滚动   背部;也就是说,一旦有了价值   获取它被认为是使用,即使   执行nextval的事务   后来中止了。这意味着中止了   交易可能会闲置   分配顺序中的“孔”   值。 setval操作永远不会   退了回来。

答案 2 :(得分:-2)

感谢Matthew Wood和Frank Heikens的回答,我想我有一个解决方案。

不是使用串行字段,而是必须创建自己的序列并将CACHE参数定义为1.这样postgres不会缓存值,每个值都将直接从序列中获取:)

感谢您的帮助:)