2010-08-04 99 views
0

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

表:

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

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

回答

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

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

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

manual

重要提示:为了避免阻塞从同一个序列获取 号 并发事务,一个 nextval操作永不卷 备用;也就是说,一旦取值为 ,它被视为使用,即使 后来执行的事务中止。这意味着被中止的 事务可能会在分配的 值序列中留下未使用的 “漏洞”。 setval操作永远不会回滚到 。

+0

我有3个“漏洞”,31个缺失的数字。 我只使用事务进行更新。插入是一次一个 - 当用户提交表单时,它不能成为交易相关的问题。 – Kayo 2010-08-04 10:01:56

+0

那么,一些处理程序确实使用序列来获得一个新的数字。现在你有一些漏洞。但是,真正的问题是什么?一个id没有任何意义,它只是一个指向唯一记录的指针。 – 2010-08-04 10:10:12

+0

ID用于统计和付款。 我没有任何问题(一切正常),但这对我的老板和我们的客户来说是一个非常大的问题:( – Kayo 2010-08-04 10:35:22

-2

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

而不是使用串行现场我要创造我自己的序列,并定义缓存参数设置为1的这种方式Postgres将不缓存值,每个人将直接从序列:)

感谢您的帮助:)

+0

不 - 这不会使您的钥匙无缝连接。它不会改变任何东西,因为默认情况下“缓存”为1,也可以用于串行列。任何被中止的交易 - 由于非法的价值错误或崩溃等 - 将占用一个不会放入您的表格的值。 – Tometzky 2010-08-06 14:15:32

+0

看看我对弗兰克的第二个评论。该设置被硬编码到源代码中并编译进去。它与CACHE设置无关。每次崩溃时您仍然会失去31个号码。 – 2010-08-06 14:58:21