linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
Intro
Lessons
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Главы
  • How it worksскоро
  • Уроки
  • База знаний
  • Собеседование
home/postgres/kb/Блокировки/relation-locks

kb/locks ── Блокировки ── intermediate

Тяжёлые блокировки отношений

Каждая команда берёт на таблицу блокировку одного из 8 режимов: от ACCESS SHARE (обычный SELECT) до ACCESS EXCLUSIVE (DROP/ALTER), который конфликтует со всеми. Блокировка держится до конца транзакции.

view as markdownaka: table-locks, heavyweight-locks, lock-modes

Тяжёлая блокировка отношения упорядочивает доступ к таблице как к объекту: пока кто-то её читает, нельзя посреди этого выполнить DROP TABLE или переписать формат через ALTER TABLE. Режим блокировки выбирает не пользователь, а сам PostgreSQL - минимально достаточный под команду.

Восемь режимов

РежимКто берёт
ACCESS SHARESELECT
ROW SHARESELECT ... FOR UPDATE/SHARE
ROW EXCLUSIVEINSERT, UPDATE, DELETE
SHARE UPDATE EXCLUSIVEVACUUM, ANALYZE, CREATE INDEX CONCURRENTLY
SHARECREATE INDEX
SHARE ROW EXCLUSIVECREATE TRIGGER, часть ALTER TABLE
EXCLUSIVEREFRESH MATERIALIZED VIEW CONCURRENTLY
ACCESS EXCLUSIVEDROP, TRUNCATE, VACUUM FULL, большинство ALTER TABLE

Правило конфликтов

Вместо матрицы 8×8 запомни: всё без слова EXCLUSIVE между собой совместимо. SELECT (ACCESS SHARE) и UPDATE (ROW EXCLUSIVE) уживаются. Режимы с EXCLUSIVE конфликтуют с записью и друг с другом, а ACCESS EXCLUSIVE - вообще со всеми, включая обычный SELECT.

До конца транзакции

Тяжёлая блокировка снимается на COMMIT/ROLLBACK, а не на конце запроса. Поэтому открытый BEGIN с давно отработавшим SELECT всё ещё держит ACCESS SHARE - и это корень каскадов (см. idle-in-transaction-cascade).

Где смотреть

sql
SELECT locktype, relation::regclass, mode, granted, pid
FROM pg_locks WHERE relation = 'flights'::regclass;

Строка с granted = f значит, что кто-то ждёт в очереди. Очередь честная (FIFO), поэтому ждущий с тяжёлым режимом останавливает за собой даже совместимые запросы. Блокировки строк сюда не попадают - они в row-locks.

§ команды

bash
SELECT mode, granted, pid FROM pg_locks WHERE relation = 'flights'::regclass;

Кто держит и кто ждёт блокировку на таблице flights

bash
LOCK TABLE flights IN ACCESS EXCLUSIVE MODE;

Явно взять самый тяжёлый режим (внутри транзакции)

bash
SET lock_timeout = '2s';

Не ждать блокировку дольше 2 секунд - страховка для DDL на проде

§ см. также

  • row-locksБлокировки строкБлокировка строки хранится в самой строке (xmax + infomask), а не в pg_locks. Режимов четыре: FOR KEY SHARE, FOR SHARE, FOR NO KEY UPDATE, FOR UPDATE. Слабые нужны, чтобы внешние ключи не сериализовали вставки.
  • idle-in-transaction-cascadeidle-in-transaction и каскад блокировокЗабытый открытый BEGIN держит блокировку до конца транзакции. Если за ним в честной FIFO-очереди встанет ALTER TABLE (ACCESS EXCLUSIVE), то даже совместимые SELECT за ним тоже повиснут - встаёт вся таблица.
  • deadlocksВзаимоблокировки (deadlock)Deadlock - цикл в графе ожидания: каждая транзакция ждёт ту, что ждёт её. PostgreSQL находит его через deadlock_timeout (1 с) и откатывает одну транзакцию с ошибкой 40P01. Лечится единым порядком блокировок.
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки