72 похожих чатов

Привет А правильно понимаю, что читающие транзакции режимов rr и Serializable

ничем не отличаются?

отличия проявляются только у пишущих

26 ответов

72 просмотра

Тогда отличаются — технически, на RR не используются SIRead locks. К каким отличиям в их поведении это приводит — см. https://wiki.postgresql.org/wiki/SSI#Rollover Да, в PostgreSQL есть специальный режим BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE READ ONLY DEFERRABLE;, в котором после того, как PostgreSQL гарантировал, что аномалии от этого невозможны, транзакции "внутри" работают точно так же, как на RR (не используют SIRead locks вообще).

RAFIZ- Автор вопроса
Yaroslav Schekin
Тогда отличаются — технически, на RR не используют...

я этот пример воспроизвёл на постгресе. Т1 упала при коммите…

RAFIZ
screenshot я этот пример воспроизвёл на постгресе. Т1 упала п...

Какой именно из обсуждавшихся? Или прямо тот, что по ссылке?

Лог двух сессий: /* Session1 */ BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; -- T1 /* Session1 */ UPDATE rollover SET n = n + (SELECT n FROM rollover WHERE id = 2) WHERE id = 1; /* Session2 */ BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; -- T2 /* Session2 */ UPDATE rollover SET n = n + 1 WHERE id = 2; /* Session2 */ COMMIT; /* Session2 */ BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE READ ONLY; -- T3 SELECT count(*) FROM pg_class; /* Session1 */ COMMIT; /* Session2 */ SELECT n FROM rollover WHERE id IN (1, 2); -- Получаю: ERROR: could not serialize access due to read/write dependencies among transactions DETAIL: Reason code: Canceled on conflict out to pivot 11820632, during read. HINT: The transaction might succeed if retried. Всё 1:1 как написано — проверяйте, что Вы делаете не так.

RAFIZ- Автор вопроса
Yaroslav Schekin
Лог двух сессий: /* Session1 */ BEGIN TRANSACTION...

1:1 всё так сделаю. скрины ж привёл

RAFIZ
1:1 всё так сделаю. скрины ж привёл

У Вас не видно последовательности и сессий на этих screenshots. Прямо скопируйте то, что я показал, в две сессии какого-то клиента (ну или копируйте в psql по одному), и выполните соответствующие запросы по одному, внимательно. > укажите свою версию 15.4. Но это обязано так работать (на последних minors), начиная с 9.1 — это простейший тест.

RAFIZ- Автор вопроса
Yaroslav Schekin
У Вас не видно последовательности и сессий на этих...

какая должна быть последовательность сессий? у меня обе сессии были открыты ещё до создания таблицы тестируемой а потом порядок транзакций точно такой же, как по ссылке версия у меня тоже PostgreSQL 15.4 on aarch64-unknown-linux-musl, compiled by gcc (Alpine 12.2.1_git20220924-r10) 12.2.1 20220924, 64-bit

RAFIZ
какая должна быть последовательность сессий? у мен...

У меня же указана, какая — вот, указал для каждого запроса. > у меня обе сессии были открыты ещё до создания таблицы тестируемой Это не имеет значения — главное, чтобы открытых транзакций в них не было (и "забытых" паралелльных транзакций, в которых Вы это же тестировали — тоже, а то мало ли... ;) ). > а потом порядок транзакций точно такой же, как по ссылке Ну вот и посмотрите, как это должно работать (и у меня работает) при таком порядке. Да попробуйте ещё раз с самого начала (выполните DROP этой таблицы), что тут думать. ;)

RAFIZ- Автор вопроса
Yaroslav Schekin
У меня же указана, какая — вот, указал для каждого...

ёёпт:) я сейчас удалю весь контейнер для эксперимента, в абсолютно пустой базе создам таблу и сделаю как в ссылке, посмотрим. upd: скачал, на всякий случай для справки указываю что получил WARNING: there is no transaction in progress то есть в исходный момент 0 транзакций в обеих сессиях

RAFIZ- Автор вопроса
RAFIZ
ёёпт:) я сейчас удалю весь контейнер для экспериме...

в общем, если хоть в Т1, хоть в Т2 после обновления прочитать эти данные, а потом закоммитить — падает именно Т1

RAFIZ- Автор вопроса
Yaroslav Schekin
У меня же указана, какая — вот, указал для каждого...

у Т3 же снепшот берётся в момент выполнения select count(*) from pg_class; ?

RAFIZ
ёёпт:) я сейчас удалю весь контейнер для экспериме...

WARNING: there is no transaction in progress Нет, стоп. ;) Этого Вы не должны видеть (это будет, если выдать COMMIT; или ROLLBACK; в сессию, где нет активной транзакции).

RAFIZ
в общем, если хоть в Т1, хоть в Т2 после обновлени...

Ну так сам пример у Вас воспроизводится правильно, так?

RAFIZ- Автор вопроса
Yaroslav Schekin
WARNING: there is no transaction in progress Нет...

> Этого Вы не должны видеть (это будет, если выдать COMMIT; или ROLLBACK; в сессию, где нет активной транзакции). ну я так и сделал. чтоб продемонстрировать что активных транзакций не было (вы выше предполагали что я мб чёт забыл закрыть)

RAFIZ- Автор вопроса
Yaroslav Schekin
Ну так сам пример у Вас воспроизводится правильно,...

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

RAFIZ
да. но почему чтение после обновления всё ломает —...

> в общем, в сообщении со скриншотами всё правильно > просто это не 1 в 1 как по ссылке. Вот же ж... а я подумал, что у Вас не работает исходный пример. А Вы можете расписать то, что Вы делаете, аналогично тому, как писал я (со screenshots я перепечатывать не собираюсь, извините)?

RAFIZ- Автор вопроса
Yaroslav Schekin
> в общем, в сообщении со скриншотами всё правильн...

вы можете не перепечатывать а просто в Т1 после апдейта добавить чтение всей таблице. и то же самое в Т2 тоже после апдейта 95% кода у вас уже есть (он взят из примера по ссылке)

RAFIZ- Автор вопроса
Yaroslav Schekin
> в общем, в сообщении со скриншотами всё правильн...

``` /* Session1 */ BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; -- T1 /* Session1 */ UPDATE rollover SET n = n + (SELECT n FROM rollover WHERE id = 2) WHERE id = 1; /* Session1 */ select * from rollover ; /* Session2 */ BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; -- T2 /* Session2 */ UPDATE rollover SET n = n + 1 WHERE id = 2; /* Session2 */ select * from rollover ; /* Session2 */ COMMIT; /* Session2 */ BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE READ ONLY; -- T3 /* Session2 */ SELECT count(*) FROM pg_class; /* Session1 */ COMMIT; /* Session1 */ ERROR: could not serialize access due to read/write dependencies among transactions DETAIL: Reason code: Canceled on identification as a pivot, during commit attempt. HINT: The transaction might succeed if retried. ```

Во-первых, заметьте, что тут не нужна T3 (то же самое получается). Во-вторых... мы же уже обсуждали именно этот случай, или мне кажется? Ладно, как бы там ни было... /* Session1 */ BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; -- T1 /* Session1 */ UPDATE rollover SET n = n + (SELECT n FROM rollover WHERE id = 2) WHERE id = 1; /* Session1 */ SELECT * FROM rollover; /* Session2 */ BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; -- T2 /* Session2 */ UPDATE rollover SET n = n + 1 WHERE id = 2; /* Session2 */ SELECT * FROM rollover; /* Session2 */ COMMIT; /* Session1 */ COMMIT; Допустимые расписания (как и то, что каждая транзакция должна видеть при чтении после UPDATE): T1 T2 1. (1, 100), (2, 10) ----> (1, 110), (2, 10) ----> (1, 110), (2, 11) T2 T1 2. (1, 100), (2, 10) ----> (1, 100), (2, 11) ----> (1, 111), (2, 11) Так вот если разрешить выполнение по этому сценарию, то (несмотря на совпадение конечного результата с первым расписанием), транзакции будут видеть после своих update следующее: T1: (1, 110), (2, 10) T2: (1, 100), (2, 11) и ни одному из этих расписаний такое не соответствует — поэтому первую PostgreSQL откатывает.

RAFIZ- Автор вопроса
Yaroslav Schekin
Во-первых, заметьте, что тут не нужна T3 (то же са...

то есть опять банальное раскладывание по возможным комбинациям очерёдности даёт все ответы…

RAFIZ
то есть опять банальное раскладывание по возможным...

Естественно, оно всегда даёт все ответы. :) Да, кстати, я вот в прошлый раз написал, что поиск цикла в графе предшествования — это просто shortcut. Но это не совсем так, т.е. это так только для того человека, который анализирует/проверяет сериализуемость — а алгоритмы обеспечения serializability как раз и строятся на предотвращении либо поиске (и разрыве, путём отката транзакций) таких циклов (или характерных для них структур, как это делает SSI) — потому что в несериализуемых расписаниях они неизбежно будут.

Похожие вопросы

Обсуждают сегодня

Гайс, вопрос для разносторонее развитых: читаю стрим с юарта, нада выделять с него фреймы с определенной структурой, если ли чо готовое, или долбаться с ринг буффером? нада у...
Vitaly
9
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
длина пакета фиксированная, или меняется?
Okhsunrog
7
Вот еще странный косяк, подскажите как бороться. Я git clone сделал себе всего embassy и примеры там запускаю. Всё хорошо. Но вот решил в cargo.toml зависимости не как в приме...
Lukutin R2AJP
5
А в каком формате фреймы? Сам формат сейчас придумываешь, или что-то готовое нужно распарсить?
Okhsunrog
5
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Добрый вечер, Пока не совсем понимаю как наладить общение между телеграм ботом и ПО для работы с сим боксом. По самому боту так понял: - Нужен некий баланс, который можно поп...
Magic
6
Всем привет, нужна как никогда, нужна помощь с IO в загрузчике. Пишу в code16 после установки сегментных регистров, пишу вывод символа. Пробовал 2 варианта: # 1 mov $0x0E, %a...
Shadow Akira
14
Раз начали говорить про embassy, то присоединюсь со своими парой вопросов. 1) Есть ли сопоставимые аналоги для асинхронного кода в emdebbed? 2) Можно ли внутри задач embassy ...
NI_isx
6
сделал сайт, прикрутил в боте сайт, и виджет логина. как автоматически логинить пользователя в аккаунт(телеграм), при входе с бота?
Александра Чернивецкая
5
Карта сайта