Значения отсутствуют в последовательном поле postgres - PullRequest
0 голосов
/ 04 августа 2010

Я управляю небольшим сайтом и использую PostgreSQL 8.2.17 (только версия, доступная на моем хосте) для хранения данных. За последние несколько месяцев на моем сервере было 3 сбоя системы базы данных, и каждый раз, когда это происходило, отсутствовали 31 идентификатор из последовательного поля (первичный ключ) в одной из таблиц. Сейчас пропало 93 удостоверения личности.

Таблица:

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

Для меня очень важно, чтобы все значения идентификаторов были там. Что я могу сделать, чтобы решить эту проблему?

Ответы [ 3 ]

2 голосов
/ 04 августа 2010

Вы не можете ожидать, что в последовательном столбце не будет дыр.

Вы можете реализовать ключ без зазора, пожертвовав параллелизмом так:

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, будет блокироваться, пока другая транзакция вставки не завершит свою работу и не запишет свои данные на диск. Это позволит вам не более 125 вставок транзакций в секунду на диск со скоростью 7500 об / мин.

Также любое удаление из таблицы registry создаст пробел.

Это решение основано на статье Последовательности без промежутков для первичных ключей А. Элейн Мустейн, которая несколько устарела.

1 голос
/ 04 августа 2010

Вам не хватает 93 записей или у вас 3 "дыры" из 31 пропущенных номеров?

Последовательность не безопасна для транзакций, она никогда не будет откатываться. Поэтому система не может создать последовательность чисел без отверстий.

Из руководства :

Важно: чтобы избежать блокировки параллельные транзакции, которые получают числа из той же последовательности, а следующая операция никогда не выполняется обратно; то есть, когда значение было извлеченный он считается использованным, даже если транзакция, которая сделала nextval позже прерывает. Это означает, что прервано транзакции могут остаться неиспользованными «дыры» в последовательности назначенных ценности. сетвальные операции никогда не бывают откат тоже.

0 голосов
/ 05 августа 2010

Благодаря ответам Мэтью Вуда и Фрэнка Хейкенса я думаю, что у меня есть решение.

Вместо использования последовательного поля я должен создать собственную последовательность и определить параметр CACHE для 1. Таким образом postgres незначения кэша и каждое из них будет взято непосредственно из последовательности :)

Спасибо за вашу помощь:)

...