Size: a a a

pgsql – PostgreSQL

2020 May 19

KK

Konstantin Knizhnik in pgsql – PostgreSQL
Yaroslav Schekin
Ах да, смысл-то в том, что в тех СУБД, которые используют "правильный" deadlock handling, эту ситуацию воспроизвести невозможно. Вот поэтому я пишу, что в deadlock detector PostgreSQL есть дефект.
А в чём проблема с deadlock detection в PG и чем он отличается от "правильного" в других СУБД?
Избежать дедлоков можно если на момент старта транзакции известен весь набор блокировок, которые она затребует. Это модель более менее работает в случае одного SQL statement-а, но совершенно не подходит для транзакции, логика работы которой управляется приложением (например написанной на PL/pgSQL)
Starvation - это не проблема постгресового дедлок детектора, а приложения, которое пытается справится с дедлоками путём повторения транзакции. Но, кстати, на мой взгляд, это вполне нормальная стратегия, если вероятность конфликта маленькая.
источник

AS

Alexey Stavrov in pgsql – PostgreSQL
Konstantin Knizhnik
А в чём проблема с deadlock detection в PG и чем он отличается от "правильного" в других СУБД?
Избежать дедлоков можно если на момент старта транзакции известен весь набор блокировок, которые она затребует. Это модель более менее работает в случае одного SQL statement-а, но совершенно не подходит для транзакции, логика работы которой управляется приложением (например написанной на PL/pgSQL)
Starvation - это не проблема постгресового дедлок детектора, а приложения, которое пытается справится с дедлоками путём повторения транзакции. Но, кстати, на мой взгляд, это вполне нормальная стратегия, если вероятность конфликта маленькая.
А как PG определяет, какую из транзакции он откатит в случае deadlock детекта?
источник

KK

Konstantin Knizhnik in pgsql – PostgreSQL
Бэкенд может только сделать харакири. Он не может прибить чужую транзакцию.
источник

AS

Alexey Stavrov in pgsql – PostgreSQL
Konstantin Knizhnik
Бэкенд может только сделать харакири. Он не может прибить чужую транзакцию.
Но умирает же одна из двух (3-ёх и т.д.), т.е. как-то же определяется, кто именно.

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

KK

Konstantin Knizhnik in pgsql – PostgreSQL
Логика работы deadlock детектора в ПГ очень простая - если я не могу получить лок в течении какого-то времени (deadlock detection timeout), то лочу всё и ищу в графе циклы. Если нашёл - бросаю ошибку и завершаю транзакцию.
источник

AS

Alexey Stavrov in pgsql – PostgreSQL
Konstantin Knizhnik
Логика работы deadlock детектора в ПГ очень простая - если я не могу получить лок в течении какого-то времени (deadlock detection timeout), то лочу всё и ищу в графе циклы. Если нашёл - бросаю ошибку и завершаю транзакцию.
Понятно, спасибо.

Тогда получается, что с 3-мя сессиями в pg можно livelock получить, а Ярослав, скорей всего имел ввиду, что выбирать нужно кем-то, а не кому повезёт.
источник

AS

Alexey Stavrov in pgsql – PostgreSQL
Кстати, а как правильно говорить livelock или starvation в данном случае?
источник

Д

Денис in pgsql – PostgreSQL
Добрый день, товарищи! Подскажите, пожалуйста, можно ли прикрутить pgbackrest к какой-нибудь web-морде для удобства администрирования?
источник

KK

Konstantin Knizhnik in pgsql – PostgreSQL
Alexey Stavrov
Но умирает же одна из двух (3-ёх и т.д.), т.е. как-то же определяется, кто именно.

Если бэкенд определяет и оба бэкенда на разных ядрах, то тогда есть вероятность, что обе умрут.
Поиск цикла в графе делается под эксклюзивной блокировкой. Вероятность того, что оба участника дедлока решат  сделать харакири достаточно мала.
Но есть другая более реальная проблема, которую мы действительно наблюдали.
И, вспомнив про неё, я склонен согласится, что в дедлок дететоре посгреса действительно есть деффект.
Под большой нагрузкой, если много транзакций конфликтуют за один и тот же ресурс (например table extension lock), то все они засыпают на этом локе и ... таймаут в них срабатывает примерно в одно и тоже  время. И все они начинают искать дедлок, для этого пытая взять ксклюзивную блокировку. И... Всё практически  встаёт.
Мы в ПгПро испытали несколько способов решить эту проблему:
1. Пытаться преварительно проверить наличие дедлка под шаред блокировкой.
2. Если кто-то уже ищет циклы в графе, то запретить ругим бэкендам заниматься дедлок детекшином
3. Запоминать в рётрах графа блокировки время последнего прохода и не ходить повторно по ним в течении какого-то времени
источник

SM

Setplus Mac in pgsql – PostgreSQL
Здравствуйте! Подскажите, пожалуйста, как грамотно решить проблему планирования осуществления некоторых действий для нескольких БД в одном кластере? Просто pg_cron может работать только для одной БД, к сожалению.
источник

YS

Yaroslav Schekin in pgsql – PostgreSQL
Alexey Stavrov
А почему до сих пор нету способа указать СУБД, сколько раз повторить всю транзакцию доп. параметром?
Потому что СУБД сама сделать это неспособна, очевидно.
источник

YS

Yaroslav Schekin in pgsql – PostgreSQL
Alexey Stavrov
Спасибо, интересно.

Усомнила фраза
where there is no row movement, session 2 would have identified the newly updated row and carried out the UPDATE/DELETE on this new row version
кажется это отсноится только к RC. В RR и S будет ошибка.
Похоже на то, да. Но для RR и S — это обычная ситуация, а вот serialization failures на RC до этого, кажется, не было.
источник

KK

Konstantin Knizhnik in pgsql – PostgreSQL
Yaroslav Schekin
Потому что СУБД сама сделать это неспособна, очевидно.
В принципе способна, для одностайтментовых транзакций. Другое дело - есть ли в этом большой смысл... И еасколько хорошо  по разному вести себя на "простых "и "сложных" транзакциях.
источник

YS

Yaroslav Schekin in pgsql – PostgreSQL
Alexey Stavrov
> Даже с мгновенным deadlock detection можно в три сессии получить livelock.
Если одна сессия получает deadlock ошубку, то другая при этом выполняется. Т.е. если вы будете ретраить свои запросы, то в конце концов 3 сессии выполнят 3 запроса.
Выбираться может случайная сессия — вот в чём проблема.
Т.е., к примеру, есть сессии приложений 1 и 2, которые выполняют длинные транзакции, систематически попадающие в deadlock. Дальше происходит следующее: PostgreSQL откатывает 1, она повторяется приложением 2 — опять deadlock, но PostgreSQL откатывает 2, повторяется 1 — опять deadlock, PostgreSQL откатывает 1... и где-то всё это мы уже видели (потенциально, это может продолжаться бесконечно). И это starvation.
источник

AS

Alexey Stavrov in pgsql – PostgreSQL
Konstantin Knizhnik
Поиск цикла в графе делается под эксклюзивной блокировкой. Вероятность того, что оба участника дедлока решат  сделать харакири достаточно мала.
Но есть другая более реальная проблема, которую мы действительно наблюдали.
И, вспомнив про неё, я склонен согласится, что в дедлок дететоре посгреса действительно есть деффект.
Под большой нагрузкой, если много транзакций конфликтуют за один и тот же ресурс (например table extension lock), то все они засыпают на этом локе и ... таймаут в них срабатывает примерно в одно и тоже  время. И все они начинают искать дедлок, для этого пытая взять ксклюзивную блокировку. И... Всё практически  встаёт.
Мы в ПгПро испытали несколько способов решить эту проблему:
1. Пытаться преварительно проверить наличие дедлка под шаред блокировкой.
2. Если кто-то уже ищет циклы в графе, то запретить ругим бэкендам заниматься дедлок детекшином
3. Запоминать в рётрах графа блокировки время последнего прохода и не ходить повторно по ним в течении какого-то времени
> Поиск цикла в графе делается под эксклюзивной блокировкой. Вероятность того, что оба участника дедлока решат  сделать харакири достаточно мала.

Я думал, что если один из участников дедлока ищет, то после поиска он делает так, чтобы его больше в этом цикле в графе небыло. Тогда второй протсо не будет умирать, так как после unlock-а граф будет без цикла.
Ну да ладно.

То, что вы описали, не предотвращает livelock с 3 сессиями:
Вот пример:
    ses 1|ses 2 |ses 3
--------------------------
t1| row 1| row 2| row 3
t2| row 2| row 3| row 1
t3| row 3| row 1| row 2
Первая сессия берёт последовательно блокировку на строки 1, 2, 3 в разные моменты времени, второая - на эти эти же строки, но в порядке 2, 3, 1 и т.д.

Если умирать будет не самый подходящий бэкенд, то после повтора будет livelock.
источник

YS

Yaroslav Schekin in pgsql – PostgreSQL
Роман Жарков
Люди, если у вас регулярно по три бекенда будут секунду висеть в дедлоке - вы далеко не уедете. Дедлоки надо предотвращать, а не "ретраить".
Ещё одна "декларация". ;) Обсуждали уже выше.
источник

AS

Alexey Stavrov in pgsql – PostgreSQL
Yaroslav Schekin
Потому что СУБД сама сделать это неспособна, очевидно.
Почему нельзя запоминать выполненные стейтменты? И выполнять надо для определённых видов ошибок...
источник

AS

Alexey Stavrov in pgsql – PostgreSQL
Yaroslav Schekin
Выбираться может случайная сессия — вот в чём проблема.
Т.е., к примеру, есть сессии приложений 1 и 2, которые выполняют длинные транзакции, систематически попадающие в deadlock. Дальше происходит следующее: PostgreSQL откатывает 1, она повторяется приложением 2 — опять deadlock, но PostgreSQL откатывает 2, повторяется 1 — опять deadlock, PostgreSQL откатывает 1... и где-то всё это мы уже видели (потенциально, это может продолжаться бесконечно). И это starvation.
Ага, я примерно тоже самое описал, но с 3-мя транзакциями.
С двумя транзакциями тоже можно придумать, да.
источник

РЖ

Роман Жарков... in pgsql – PostgreSQL
Yaroslav Schekin
Ещё одна "декларация". ;) Обсуждали уже выше.
Чего только выше нет! А эта декларация проверяется калькулятором  или даже листочком с ручкой. Надо только примерно прикинуть при каком значении deadlock_timeout и примерной вероятности дедлока бекенды перестанут успевать обслуживать клиентов.
источник

YS

Yaroslav Schekin in pgsql – PostgreSQL
Konstantin Knizhnik
А в чём проблема с deadlock detection в PG и чем он отличается от "правильного" в других СУБД?
Избежать дедлоков можно если на момент старта транзакции известен весь набор блокировок, которые она затребует. Это модель более менее работает в случае одного SQL statement-а, но совершенно не подходит для транзакции, логика работы которой управляется приложением (например написанной на PL/pgSQL)
Starvation - это не проблема постгресового дедлок детектора, а приложения, которое пытается справится с дедлоками путём повторения транзакции. Но, кстати, на мой взгляд, это вполне нормальная стратегия, если вероятность конфликта маленькая.
Уже написал про проблему. В других СУБД есть какой-то приоритет при ROLLBACK — в описанной ситуации всегда будет откатываться транзакции сессии 2, например. Поэтому прогресс гарантирован.

> Starvation - это не проблема постгресового дедлок детектора, а приложения

Нет, это именно низкокачественная реализация (потому что, опять-таки, проблема описана в учебниках по transaction processing, там приводятся "классические" решения (prioritizing), и то, что PostgreSQL их не реализует, характеризует его как-то так, IMNSHO). И приложение должно так с ними справляться.
источник