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/Блокировки/lightweight-predicate-locks

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

Лёгкие, spin- и предикатные блокировки

Под тяжёлыми блокировками лежат лёгкие LWLock (защита структур памяти) и spinlock (пара полей). Их не видно в pg_locks, только в wait_event. Отдельно - предикатные SIReadLock для Serializable, которые не блокируют.

view as markdownaka: lwlock, spinlock, predicate-locks, wait-events

У PostgreSQL три слоя блокировок под разные задачи и время жизни.

СлойЗащищаетЖивётВидно
Тяжёлыетаблицы, строкидо конца транзакцииpg_locks
LWLockструктуры в shared memoryвремя операцииwait_event
Spinlockпара полейдесятки тактовнигде

LWLock

Лёгкая блокировка охраняет конкретную структуру в разделяемой памяти: буфер кеша при чтении (см. buffer-cache), буфер WAL при вставке, таблицу хешей. Два режима (разделяемый/исключительный), но в отличие от тяжёлых - держится микросекунды, не имеет детектора deadlock (берётся в фиксированном порядке, цикл невозможен) и не попадает в pg_locks. Имя говорит о цели: WALInsert, BufferContent, LockManager.

Spinlock

Защищает буквально пару инструкций. Не усыпляет процесс - крутится в busy-wait, пока замок занят. Оправдан только при микроскопическом времени удержания: переключение контекста стоило бы дороже. Нигде не учитывается.

Wait events

Раз LWLock и тяжёлые ожидания не сводятся в одну таблицу, общий язык - wait_event_type/wait_event в pg_stat_activity:

sql
SELECT wait_event_type, wait_event, count(*)
FROM pg_stat_activity WHERE state = 'active'
GROUP BY 1, 2 ORDER BY count(*) DESC;

Lock - тяжёлая блокировка, LWLock - лёгкая, IO - диск, пустой тип

  • работа на CPU. Узкое место ищут семплированием: снять много раз и посмотреть, что чаще.

Предикатные блокировки (SIReadLock)

Их использует Serializable/SSI (см. serializable-ssi), и они не блокируют. При чтении на Serializable транзакция оставляет метку SIReadLock - «я это читала». Никто не ждёт. Но если другая транзакция пишет туда, где стоит чужая метка, и шаблон зависимостей опасен, при коммите будет ошибка сериализации 40001. Огрубляются кортеж → страница → таблица ради памяти, ценой ложных срабатываний.

sql
SELECT count(*) FROM pg_locks WHERE mode = 'SIReadLock';

В отличие от deadlocks, конфликт SSI всплывает не циклом, а на коммите. Тяжёлый слой описан в relation-locks.

§ команды

bash
SELECT wait_event_type, wait_event FROM pg_stat_activity WHERE state='active';

На чём прямо сейчас ждут активные бэкенды

bash
SELECT mode, count(*) FROM pg_locks WHERE mode='SIReadLock' GROUP BY 1;

Следы предикатных блокировок Serializable

bash
BEGIN ISOLATION LEVEL SERIALIZABLE;

Включить SSI: чтения начнут оставлять SIReadLock

§ см. также

  • deadlocksВзаимоблокировки (deadlock)Deadlock - цикл в графе ожидания: каждая транзакция ждёт ту, что ждёт её. PostgreSQL находит его через deadlock_timeout (1 с) и откатывает одну транзакцию с ошибкой 40P01. Лечится единым порядком блокировок.
  • relation-locksТяжёлые блокировки отношенийКаждая команда берёт на таблицу блокировку одного из 8 режимов: от ACCESS SHARE (обычный SELECT) до ACCESS EXCLUSIVE (DROP/ALTER), который конфликтует со всеми. Блокировка держится до конца транзакции.
  • row-locksБлокировки строкБлокировка строки хранится в самой строке (xmax + infomask), а не в pg_locks. Режимов четыре: FOR KEY SHARE, FOR SHARE, FOR NO KEY UPDATE, FOR UPDATE. Слабые нужны, чтобы внешние ключи не сериализовали вставки.
  • buffer-cacheБуферный кеш и вытеснениеБуферный кеш - разделяемая память (shared_buffers), нарезанная на буферы по 8 КБ. Все бэкенды работают с одним кешем. Когда место кончается, буфер выселяется по приближённому алгоритму clock-sweep (счётчик usage_count), а не по честному LRU.
  • serializable-ssiSerializable и SSISerializable в PostgreSQL построен на снимке Repeatable Read плюс отслеживание опасных зависимостей чтения-записи между транзакциями (SSI). Транзакции не блокируются: сервер запоминает, что они читали, через предикатные блокировки SIRead, и если складывается опасный цикл, откатывает одну с ошибкой 40001.
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки