Каковы условия возникновения сбоя сериализации? - PullRequest
11 голосов
/ 09 октября 2011

Страница справочника PostgreSQL об уровне сериализуемой изоляции гласит:

[Как] уровень повторяемого чтения, приложения, использующие этот уровень, должны быть готовы повторить транзакции из-за сериализациисбои.

Каковы условия возникновения сбоя сериализации на уровнях Repeatable Read или Serializable?

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

По сути, я пытаюсь понять, что происходит в случае сбоя сериализации и как возникают ошибки сериализации.

Ответы [ 3 ]

6 голосов
/ 03 апреля 2012

Существует множество возможных причин сбоев сериализации. Технически, взаимоблокировка между двумя транзакциями является одной из форм сбоя сериализации и может произойти на любом уровне изоляции, если в схему (структуру базы данных) одновременно вносятся изменения. Поскольку вы спрашиваете о PostgreSQL, вы должны знать, что в PostgreSQL этот тип ошибки сериализации получает отдельный SQLSTATE от остальных: «40P01». Все другие ошибки сериализации возвращают «40001». Остальная часть этого ответа будет сосредоточена на этих неблокируемых вариантах в PostgreSQL.

За пределами живой реплики («горячее резервирование») это может происходить только на двух более жестких уровнях изоляции: REPEATABLE READ и SERIALIZABLE. На уровне REPEATABLE READ это может произойти только из-за конфликтов записи - две параллельные транзакции пытаются обновить или удалить одну (существующую) строку. Первая транзакция, которая предпримет попытку, блокирует строку и продолжается. Если он фиксируется, вторая транзакция завершается с ошибкой сериализации. Если первая транзакция откатывается по какой-либо причине, заблокированная транзакция освобождается для продолжения и получает собственную блокировку строки. Такое поведение в сочетании с одним «моментальным снимком» на время транзакции также называется SNAPSHOT ISOLATION.

До версии PostgreSQL 9.1 транзакции SERIALIZABLE работали точно так же. Начиная с 9.1 PostgreSQL использует новый метод, называемый Serializable Snapshot Isolation, чтобы гарантировать, что поведение любого набора сериализуемых транзакций полностью соответствует некоторому последовательному (по одному) выполнению этих транзакций. При использовании транзакций SERIALIZABLE в 9.1 ваше приложение должно быть подготовлено к сбоям сериализации в любом операторе, кроме ROLLBACK - даже в транзакциях только для чтения и даже в COMMIT. Для получения дополнительной информации см. Страницу документации PostgreSQL по адресу http://www.postgresql.org/docs/current/interactive/transaction-iso.html или страницу Wiki, в которой приведены примеры возможных сбоев сериализации на новом, более строгом уровне изоляции при http://wiki.postgresql.org/wiki/SSI

.

Если вы используете функцию горячего резервирования, вы можете получить ошибку сериализации на реплике, доступной только для чтения, если существует длительный запрос, для которого поддержание стабильного представления данных потребовало бы от базы данных слишком большой репликации для репликации. долго. Существуют параметры конфигурации, позволяющие сбалансировать «свежесть» реплицированных данных с допустимым отклонением для длительных запросов. Некоторым пользователям может потребоваться создать более одной реплики, чтобы они могли иметь обновленные данные (возможно, даже выбрав синхронную репликацию), в то же время позволяя другому отстать по мере необходимости для обслуживания долго выполняющихся запросов.

Отредактируйте, чтобы предоставить еще одну ссылку: статья под названием Сериализуемая изоляция моментальных снимков в PostgreSQL , представленная на 38-й Международной конференции по очень большим базам данных, дает больше деталей и перспектив, чем другие ссылки, а также ссылки на документы который заложил основу для этой реализации.

5 голосов
/ 09 октября 2011

Для REPEATABLE READ этот пример будет делать:

Подготовительный этап:

psql-0> CREATE TABLE foo(key int primary key, val int);
CREATE TABLE
psql-0> INSERT INTO foo VALUES(1, 42);

Теперь следите за частью psql- X , указывающей на чередование действий:

psql-1> BEGIN ISOLATION LEVEL REPEATABLE READ;
psql-1> UPDATE foo SET val=val+1;
UPDATE 1
psql-2> BEGIN ISOLATION LEVEL REPEATABLE READ;
psql-2> UPDATE foo SET val=val+1;
*** no output, transaction blocked ***

psql-1> COMMIT;

psql-2> *** unblocks ***
ERROR:  could not serialize access due to concurrent update

Пример для SERIALIZABLE приведен в документации для PostgreSQL 9.1 и здесь не должно быть проблем.

4 голосов
/ 09 октября 2011

Если это кому-нибудь поможет, вот стенограмма из #postgresql на Freenode:

[14:36] Каковы условия возникновения ошибки сериализации?

[14:36] ^ Каковы условия для встречи с ошибка сериализации?

[14:37] Есть ли разработчик PostgreSQL, который может идентифицировать условия сбоя сериализации?

[14:38] http://www.postgresql.org/docs/current/static/transaction-iso.html#XACT-SERIALIZABLE

[14:43] "любой набор одновременных сериализуемых транзакции будут иметь тот же эффект, как если бы они были запущены одна время "

[14:44] По каким правилам PostgreSQL двигатель следует?

[14:44] Т.е. Если строка изменена, это вызывает сбой?

[14:44] сериализуемый режим изоляции в 9.1 действительно комплекс

[14:45] Я понял.

[14:45] Я также прочитал, что уровень Serializable был как-то "исправлено"

[14:45] dtrebbien: до 9.1 основное правило что если транзакция пытается изменить строку, текущее значение которой не это видно, это провал

[14:46] RhodiumToad: Это интересно.

[14:46] Кроме того, доступ к значению, верно?

[14:46] dtrebbien: в дополнение к тому, что другие сказанное, основная предпосылка позади этого - обнаружение циклов Зависимости

[14:47] Ох.

[14:50] Справедливо ли сказать, что в 9.1 правила для запуск уровня изоляции были сделаны более сложными для в основном сократить "ложноположительные" аномалии сериализации?

[14:51] они были сделаны сложными, потому что чем проще rulex не уловил всех аномалий сериализации

[14:51] Ах! Понятно.

[14:51] Так вот почему в примечаниях к выпуску сказано "Фиксированный".

[14:52] dtrebbien: доступ к невидимым значениям не было ошибкой, потому что он просто получил значение, которое было видно при время снимка.

[14:53] dtrebbien: сериализуемые запросы только для чтения просто посмотрите статическое состояние базы данных на момент их моментального снимка.

[14:54] dtrebbien: кроме маленькой морщинки с TRUNCATE, все проблемы с сериализацией связаны с запросами на чтение / запись

[15:03] RhodiumToad, johto, selenamarie и peerce: Не возражаете, если я отправлю запись этого разговора в стек? Переполнение

[15:07] dtrebbien: обязательно :) 1077 *

[15:07] Не знаю, поможет ли это кому-нибудь. Это может.

[15:08] dtrebbien: я опубликовал свои заметки от Кевина Гритнер говорит об этом здесь: http://www.chesnok.com/daily/2011/03/24/raw-notes-from-kevin-grittners-talk-on-ssi/

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