Кэширование последовательностей Oracle - PullRequest
8 голосов
/ 04 марта 2010

Я пытаюсь реализовать последовательность в базе данных Oracle, чтобы действовать как создатель суррогатного ключа для таблицы.Из соображений производительности я хочу, чтобы эта последовательность кэшировалась.Я читал, что при использовании кэшированных последовательностей возможны подводные камни, поскольку откаты и ошибки экземпляров приводят к пропущенным значениям.

Это заставило меня задуматься.Допустим, я создаю последовательность с размером кэша 100. Затем я делаю вставку из 50 записей в свою таблицу со значением последовательности в качестве первичного суррогатного ключа.После фиксации текущее значение последовательности еще не было записано на диск.Предположим, в этот момент у меня произошел сбой экземпляра.Когда база данных возвращается, я понимаю, что текущее значение последовательности будет сброшено до последнего значения, записанного на диск.

Если бы я попытался вставить еще 50 записей в мою таблицу, я сейчас сломаюограничение первичного ключа, поскольку последовательность была сброшена с диска до последнего состояния, а первичные ключи теперь используются повторно?Если это так, как бы я это предотвратить?

Ответы [ 3 ]

15 голосов
/ 04 марта 2010

Нет, это не так.

Ваша последовательность продолжится на 101, значения от 50 до 100 будут отсутствовать.

Единственная причина отключить кэширование последовательности - это попытка избежать пробелов в последовательности, что не относится к большинству первичных ключей.

Вас может заинтересовать эта статья , в которой говорится, что

Недостаток создания последовательности с кешем то что если система происходит сбой, все кэшированные последовательности значения, которые не были использованы, будут "потерял". Это приводит к «разрыву» в назначенные значения последовательности. Когда система возвращается, Oracle будет кэшировать новые номера с того места, где оно осталось в последовательности, игнорируя так называемые «потерянные» значения последовательности.

4 голосов
/ 06 мая 2013

Оказывается, что это не так (или больше не соответствует действительности). Завершение работы и перезапуск экземпляра не приводит к потере кэшированных значений. Простой тест с кешем = 1000.

SQL> выбрать order.currval из двойного;

CURRVAL

    22

SQL> выбрать неупорядоченный.currval из двойного

CURRVAL

    24

SQL> ОТКЛЮЧЕНИЕ НЕМЕДЛЕННО SQL> STARTUP

NEXTVAL

    23

SQL> выбрать неупорядоченный.nextval из двойного;

NEXTVAL

    25

Кроме того, ALL_SEQUENCES.LAST_NUMBER не содержит последний последний номер, указанный в последовательности, кроме как при запуске и перед первым NEXTVAL. После первого NEXTVAL, он содержит последний обслуживаемый номер плюс CACHE_SIZE. Это не изменится, пока не будет создан новый кеш. Однако при завершении работы он, по-видимому, сбрасывается до последнего обслуживаемого номера.

4 голосов
/ 04 марта 2010

Скажем, кэш имеет значения 101-200. Значение, записанное на диске, равно 201. Ваша вставка использует 101-150. Экземпляр падает. Экземпляр запускается. При следующем использовании последовательности будет кэшировано 201–300.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...