Блокировки и конкурентный доступ в PostgreSQL
MVCC и блокировки
PostgreSQL использует MVCC: читатели обычно не блокируют писателей и наоборот. Физические блокировки строк возникают при конфликте записи двух транзакций над одной версией строки.
Классическая теория (Shared / Exclusive) на уровне строк реализована через видимость версий; явные блокировки задаются командами SELECT … FOR UPDATE и LOCK TABLE.
Блокировки таблиц (уровни)
| Уровень | Типичная операция | Блокирует SELECT? | Блокирует UPDATE? |
|---|---|---|---|
ACCESS SHARE | SELECT | Нет | Нет |
ROW SHARE | SELECT FOR UPDATE/SHARE | Нет | Нет |
ROW EXCLUSIVE | INSERT, UPDATE, DELETE | Нет | Другие ROW EXCLUSIVE |
SHARE UPDATE EXCLUSIVE | VACUUM, ANALYZE | Нет | Да |
ACCESS EXCLUSIVE | DROP TABLE, ALTER TABLE | Да | Да |
Явные блокировки строк
BEGIN;
-- Эксклюзивная блокировка выбранных строк до COMMIT
SELECT * FROM inventory
WHERE item_id = 1
FOR UPDATE;
UPDATE inventory SET quantity = quantity - 1 WHERE item_id = 1;
COMMIT;
| Вариант | Поведение |
|---|---|
FOR SHARE | Разделяемая блокировка: чтение FOR SHARE разрешено, запись — нет |
FOR UPDATE NOWAIT | Ошибка сразу, если строка занята |
FOR UPDATE SKIP LOCKED | Пропуск занятых строк (очереди задач) |
Пример очереди заказов:
SELECT order_id
FROM orders
WHERE status = 'new'
ORDER BY order_date
FOR UPDATE SKIP LOCKED
LIMIT 1;
Блокировки действуют до COMMIT или ROLLBACK.
Взаимоблокировки (deadlock)
Цикл: транзакция A ждёт ресурс B, B ждёт A. PostgreSQL обнаруживает цикл процессом deadlock detector (интервал deadlock_timeout, по умолчанию 1 с) и откатывает одну транзакцию.
Профилактика:
- блокировать таблицы/строки в одинаковом порядке;
- держать транзакции короткими;
- использовать
NOWAIT/SKIP LOCKEDв очередях; - не повышать изоляцию без необходимости.
Диагностика
SELECT
blocked_locks.pid AS blocked_pid,
blocked_activity.usename AS blocked_user,
blocking_locks.pid AS blocking_pid,
blocking_activity.usename AS blocking_user,
blocked_activity.query AS blocked_query,
blocking_activity.query AS blocking_query
FROM pg_catalog.pg_locks blocked_locks
JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid
JOIN pg_catalog.pg_locks blocking_locks
ON blocking_locks.locktype = blocked_locks.locktype
AND blocking_locks.database IS NOT DISTINCT FROM blocked_locks.database
AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
AND blocking_locks.pid != blocked_locks.pid
JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
WHERE NOT blocked_locks.granted;
SHOW deadlock_timeout;
Advisory-блокировки
Логические замки приложения без привязки к строке таблицы:
SELECT pg_advisory_lock(42);
-- критическая секция
SELECT pg_advisory_unlock(42);
Контрольные вопросы
- Почему обычный
SELECTне блокируетUPDATEв PostgreSQL? - Чем
FOR UPDATEотличается отFOR SHARE? - Для чего нужен
SKIP LOCKED? - Как СУБД разрешает deadlock?
См. также
См. также
Другие статьи этого же раздела в боковом меню (как на странице «О разделе»). Вот SQL как раз обеспечивает такую связь и это главное отличие реляционных БД - реляции (relations), что означает связи. Знакомимся с языком - ставим программы, запускаем, выполняем первые запросы. От файлового хранения к реляционной и современной мультимодельной СУБД — термины, причины появления SQL и базовая классификация систем. Домены, атрибуты, кортежи и отношения — свойства реляционных таблиц и ограничения целостности при проектировании схемы. Функциональные зависимости, нормальные формы 1НФ–3НФ, аномалии обновления и осознанная денормализация при проектировании схемы. Метаданные СУБД через information_schema и pg_catalog — запросы к структуре таблиц, ключей и индексов в PostgreSQL. Логическое и физическое резервное копирование, pg_dump, pg_restore, WAL и восстановление на точку во времени (PITR). Логический порядок выполнения SELECT, проекция, WHERE, DISTINCT, ORDER BY и правила читаемого форматирования запросов. Скалярные и коррелированные подзапросы, EXISTS против IN, особенности NULL и выбор между подзапросом и JOIN. AND, OR, NOT, приоритет операторов, NULL и UNKNOWN, IS NULL, NOT IN и IS DISTINCT FROM в PostgreSQL. Учебная схема интернет-магазина для PostgreSQL — DDL и примеры запросов по темам курса SQL. Принципы работы SQL-движка - подключение к СУБД, разбор и выполнение запроса и возврат результата клиенту.SQL - язык структурированных запросов
Первые шаги с SQL
Эволюция систем хранения данных
Реляционная модель данных
Нормализация данных
Словарь данных и системные каталоги
Резервное копирование и восстановление PostgreSQL
Оператор SELECT — синтаксис и стиль
Подзапросы, EXISTS и IN
Фильтрация и трёхзначная логика
Практикум shop_data
Принципы работы SQL-движка