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

Помогите разобраться В доках и в книжке по постгресу не могу

понять как такое может быть

Есть дедлок, 2+ транзакции внутри себя работают с одной таблицей в которую инсертят записи, из которой селектят записи, и иногда делают select for update, но судя по коду и ошибке это не этот случай тк for update делается только после инсертов. И ловится дедлок.

Ошибка выглядит так:

2023-08-16 14:22:04.366 GMT [196] ERROR: deadlock detected
2023-08-16 14:22:04.366 GMT [196] DETAIL: Process 196 waits for ShareLock on transaction 2382; blocked by process 199.
Process 199 waits for ShareLock on transaction 2383; blocked by process 196.
Process 196: INSERT INTO "ResourceOccupationEntity" AS t ("poolId","resourceId","statusJson") VALUES ($1, $2, $3) ON CONFLICT DO NOTHING
Process 199: INSERT INTO "ResourceOccupationEntity" AS t ("poolId","resourceId","statusJson") VALUES ($1, $2, $3) ON CONFLICT DO NOTHING

в доке написано что ShareLock берется только во время "CREATE INDEX (without CONCURRENTLY)."
Но это 99.99% не так, тк код который делает инсерт происходит точно после того как отработал код который накатывает схему, в которой может быть какой-то индекс.

Далее могу предположить что "ShareLock" из лога соответствует "Row-Level Lock - FOR SHARE" (хотя ни в доке ни в книжке это не описано). Также смотрю что в книге, в разделе о дедлоках описано что при апдейте выводится также в логи название "ShareLock", и вызвано это блокировкой строки, которая апдейтится. По доке блокировка на строчку которую берет UPDATE это как раз "FOR SHARE". Но самое интересно что такая блокировка не берется при инсерте.
По доке при инсерте берется только табличный "ROW EXCLUSIVE (RowExclusiveLock)" который также берется при UPDATE, но он не конфликтует сам с собой.

В итоге по доке нет ни 1го кейса когда мои запросы (и соответствующие их блокировки) бы конфликтовали, но тем не менее есть дедлок.

Кривая дока? Баг в постгресе?

Помогите пожалуйста 🙂

20 ответов

15 просмотров

> в доке написано И правильно написано (если не считать того, что некоторые расширения могут его использовать, ну и в LOCK можно задать что угодно), насколько я помню. > Но это 99.99% не так, Так что наоборот. ;) > код который делает инсерт происходит точно после того как отработал код который накатывает схему, в которой может быть какой-то индекс. И что из того, что он происходит после? Важно только то, в той же транзакции или нет. > хотя ни в доке ни в книжке это не описано Потому что это неправда. ;) Ну и остальное — Ваши фантазии, извините (насколько я пока вижу).

Artem-Sokolov Автор вопроса
Yaroslav Schekin
> в доке написано И правильно написано (если не с...

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

Artem-Sokolov Автор вопроса
Yaroslav Schekin
> в доке написано И правильно написано (если не с...

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

Artem-Sokolov Автор вопроса
Yaroslav Schekin
> в доке написано И правильно написано (если не с...

я правильно понял что вы утверждаете что SharedLock в логах может быть ТОЛЬКО при взятии SHARE (ShareLock), который по доке "Acquired by CREATE INDEX (without CONCURRENTLY)." + можно самому или в экстеншенах? но это же не правда, в книге приводится что такое же название выводится логах при update

Artem Sokolov
точно не в тойже транзакции. это прям разные стади...

А это воспроизводится (особенно хорошо, если в тестовом окружении)? Если да — log_statement = all и всё выяснится. > то я баг постгреса словил Я не верю, что PostgreSQL с чего-то ставит ShareLock там, где он совсем не нужен. > что конкретно вы оспариваете - не понятно Ваши фантазии по поводу того, что ShareLock — это "на самом деле" Row-Level Lock - FOR SHARE и так далее.

Artem-Sokolov Автор вопроса
Artem Sokolov
screenshot окей, почему тогда в книге ShareLock при update ?

Это ShareLock на соседскую транзакцию. В надежде что когда она закончится удастся продолжить свою

Artem Sokolov
я правильно понял что вы утверждаете что SharedLoc...

Нет, я утверждаю только то, что ShareLock <> какому-либо row lock, и всё. > в книге приводится что такое же название выводится логах при update Правильно приводится — Вы внимательно смотрите в документации, в каком разделе это написано. > окей, почему тогда в книге ShareLock при update ? Разве это ShareLock таблицы?

Artem-Sokolov Автор вопроса
Yaroslav Schekin
Нет, я утверждаю только то, что ShareLock <> каком...

как это понимать? в разделе блокировок строк приводится что происходит блокирование строк и в логах ShareLock но вы утверждаете "ShareLock <> какому-либо row lock, и всё." при этом как я понимаю из вопрос "Разве это ShareLock таблицы?" то это и не табличный лок. можете объяснить?

Artem Sokolov
как это понимать? в разделе блокировок строк прив...

> приводится что происходит блокирование строк Строк, а не таблиц. > и в логах ShareLock ShareLock чего? Вот цитата из Вашего лога: ShareLock on transaction 2382 Какое там третье слово? ;) Ладно, кроме шуток: > то это и не табличный лок. Вот именно. Таким образом отражается ожидание транзакциями друг друга... и, кстати, в документации я этого тоже сходу не вижу (хотя это должно быть в разделе https://www.postgresql.org/docs/current/mvcc.html , казалось бы) — написали бы Вы bug report / documentation comment, что ли...

У вас классический deadlock: Session 1: create table t(x integer primary key); begin; insert into t values (1) on conflict do nothing; Session2: begin; insert into t values (2) on conflict do nothing; insert into t values (1) on conflict do nothing; Session1: insert into t values (2) on conflict do nothing;

Konstantin Knizhnik
У вас классический deadlock: Session 1: create ...

Или не классический — мы транзакций целиком не видели (но скорее всего да, так и есть). ;)

Artem-Sokolov Автор вопроса
Konstantin Knizhnik
У вас классический deadlock: Session 1: create ...

да, только в приложении это "невозможно" идет create table всех, синхронно только после этого приложение начинает принимать запросы приходит 2 запроса в которых в транзакции пачка инсертов. и вот как они между собой конфликтуют, пока не пойму. ну либо не инсерты конфликтуют... но почему-то именно на этих стейтментах детектится дедлок

Artem Sokolov
да, только в приложении это "невозможно" идет crea...

Ну так вон же пример того, как именно это происходит. Опять-таки, Вам бы выяснить, что происходит в этих транзакциях, от начала и до deadlock.

Sergey Gr
А вот и ShareLock в книге

Книга — это хорошо... только вот получается так, что [все] мы об этом откуда-то знаем, а вот документация PostgreSQL — нет. ;)

Sergey Gr
А я вчера жаловался на документацию.

Если у Вас есть силы и желание её улучшать — надо жаловаться не только тут, но и в -docs (авось, подействует). ;)

Artem Sokolov
да, только в приложении это "невозможно" идет crea...

create table   тут не причём - он до старта транзакции.

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

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

а через ESC-код ?
Alexey Kulakov
29
30500 за редактор? )
Владимир
47
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
13
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
в JclConsole объявлено так: function CtrlHandler(CtrlType: DWORD): BOOL; stdcall; - где ваше объявление с stdcall? у вас на картинке нет stdcall
Karagy
8
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
6
Ребят в СИ можно реализовать ООП?
Николай
33
program test; {$mode delphi} procedure proc(v: int32); overload; begin end; procedure proc(v: int64); overload; begin end; var x: uint64; begin proc(x); end. Уж не знаю...
notme
6
у вас два процесса. один посылает другому сигнал. у вас есть код обоих процессов? если всё не так - расскажите как оно на самом деле. а именно кто кому чего, есть-ли консоли,...
Karagy
6
Карта сайта