Долгая транзакция и раздувание таблиц
Вопрос
Сервис открыл транзакцию и забыл её закрыть: соединение несколько часов висит в состоянии idle in transaction. Что происходит с базой?
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Варианты ответа
- Ничего: транзакция ничего не делает и ресурсов не держит
- VACUUM не удалит мёртвые версии после её старта, таблицы раздуютсяправильный ответ
- PostgreSQL через 5 минут откатит её автоматически по таймауту
- Все остальные транзакции ждут её: она держит блокировку на всю базу
Разбор
Пока жива транзакция со старым снимком, любая версия строки, которую она теоретически может увидеть, считается нужной, и VACUUM её не удалит. В нагруженных таблицах копятся мёртвые строки (bloat), растут индексы, замедляются запросы. Кроме того, она держит блокировки на строки и таблицы, которые успела взять, но не на всю базу. Автоматически такая транзакция не завершается, пока не задан idle_in_transaction_session_timeout; его и стоит выставлять, а искать виновников через pg_stat_activity по state и xact_start.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Предыдущий вопрос
Взаимоблокировки: как ловить и предотвращать
Следующий вопрос
MVCC и VACUUM в PostgreSQL
Термины по теме
Ещё по теме «Транзакции и изоляция»
- Advisory-блокировки в PostgreSQL
- Как избежать deadlock при переводах
- VACUUM или VACUUM FULL на проде
- Зачем нужна заморозка и что такое wraparound
- Что делает PostgreSQL при deadlock
- Уровень изоляции по умолчанию в PostgreSQL
- Как обеспечивается Durability
- ACID