Обновить

PostgreSQL в проде: блокировки, bloat и ночные пересчёты. Три инцидента и как их чинили

Уровень сложностиСредний
Время на прочтение9 мин
Охват и читатели4.7K
Всего голосов 9: ↑8 и ↓1+11
Комментарии10

Комментарии 10

А купить PG Pro денег не выделяют?

Да, бюджет распилили)))

Но, а если серьезно, то ни один из трёх инцидентов он бы не закрыл. Bloat от массового UPDATE, очередь за ACCESS EXCLUSIVE и дедлоки из-за разного порядка блокировок — это уже про MVCC и архитектуру приложения, а не про дистрибутив.

Все эти проблемы одинаково воспроизводятся на ванильном PG, Postgres Pro и, по сути, любой другой сборке.

HTTP-вызов внутри транзакции лицензией, к сожалению, тоже не лечится)

Ну там pg_procompact и все такое...

"HTTP-вызов внутри транзакции лицензией, к сожалению, тоже не лечится) "
Хм, а в ОДБ все ок с этим было?

pg_procompact и т.д. — задача у них одна: перепаковать раздутую таблицу онлайн. Мы pg_repack’ом это и делали.

Только это про последствия. Перепаковывать можно хоть каждое утро, если ночью прилетает update на 16 млн строк, к вечеру таблица снова раздута. Так что дальше пошли батчи, fillfactor и отдельный autovacuum на эту таблицу, а два самых тяжёлых пересчёта вообще переписали с update на пересборку.

Про Oracle — да, тут момент честный. Первый инцидент там почти не всплывал: старая версия уходит в undo, а не остаётся мёртвой в самой таблице. Но бесплатно не бывает — своя цена в undo/redo.

А второй и третий Oracle бы не спас. Транзакция, повисшая на HTTP-вызове, точно так же держит блокировки и мешает DDL, а разъехавшийся порядок захвата так же кончается дедлоком.

Так что PgPro vs обычный Postgres — не совсем та ось. Механика существенно отличается только в первом кейсе

Разница в том, что к утру Pro разгреб бы бэклог из 16 млн записей и никто бы ничего бы и не заметил. Ну т.е. заметил, но это не было бы инцидентом.

Ну и pg_repack все равно потребует лок на таблицу. А pg_procompact - нет.
Вообщем, я к чему веду... Вы сэкономили 3 копейки, получили проблем на 100 руб.

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

Раскусили) Весь отдел годами кормится с одного @Transactional, натянутого на HTTP-вызов. Купим Pro и что, он нам бэкенд отрефакторит? Придётся снова уходить домой в шесть, кто ж на такое пойдёт)

Не имеет отношения к хабу Java.

Второй инцидент как раз чисто джавовый: @Transactional на методе, а внутри — внешний HTTP-вызов. Сервис затупил, транзакция осталась висеть в idle in transaction и через ALTER утянула весь прод. Третий кейс — вообще enterprise-платформа на Spring под Hibernate. Да и часть фиксов не в базе, а в коде: вынесли вызовы за границу транзакции, сделали outbox. Разбирали через Postgres, но грабли бэкендерские — так что хаб по делу.

Очередь на таблице — только с FOR UPDATE SKIP LOCKED.

только если на эту таблицу никакие не ссылаются, иначе FOR NO KEY UPDATE SKIP LOCKED или оно рискует застрять в другом не совсем очевидном месте )

Точное замечание, спасибо!)

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации