postgres locks LockManager - ghdrako/doc_snipets GitHub Wiki
| Lock Level | Blocks Reads? | Blocks Writes? | Acquired By |
|---|---|---|---|
| ACCESS SHARE | No | No | SELECT |
| ROW SHARE | No | No | SELECT FOR UPDATE/SHARE |
| ROW EXCLUSIVE | No | No | INSERT, UPDATE, DELETE |
| SHARE UPDATE EXCLUSIVE | No | No | VACUUM, CREATE INDEX CONCURRENTLY, ALTER TABLE (some) |
| SHARE | No | Yes | CREATE INDEX (without CONCURRENTLY) |
| SHARE ROW EXCLUSIVE | No | Yes | CREATE TRIGGER, some ALTER TABLE |
| EXCLUSIVE | No | Yes | REFRESH MATERIALIZED VIEW CONCURRENTLY |
| ACCESS EXCLUSIVE | Yes | Yes | DROP, TRUNCATE, most ALTER TABLE, VACUUM FULL, CLUSTER |
The key insight: ACCESS EXCLUSIVE is the only lock that blocks reads. Everything else allows SELECT queries to continue. But anything from SHARE upward blocks writes (INSERT, UPDATE, DELETE)
Postgres Lock Types
- ACCESS SHARE
- ROW SHARE
- ROW EXCLUSIVE
- SHARE UPDATE EXCLUSIVE
- SHARE
- SHARE ROW EXCLUSIVE
- EXCLUSIVE
- ACCESS EXCLUSIVE
Share/Exclusive Types
- ACCESS SHARE
- ROW SHARE
- ROW EXCLUSIVE
- SHARE UPDATE EXCLUSIVE
- SHARE
- SHARE ROW EXCLUSIVE
- EXCLUSIVE
- ACCESS EXCLUSIV
Row/Access Types
- ACCESS SHARE
- ROW SHARE
- ROW EXCLUSIVE
- SHARE UPDATE EXCLUSIVE
- SHARE
- SHARE ROW EXCLUSIVE
- EXCLUSIVE
- ACCESS EXCLUSIVE
Lock Maager PG18+
- Struktura zarządzania blokadami jest teraz bardziej rozproszona (sharded / partitioned).
- Zamiast jednej globalnej blokady LockMgrLock, istnieje wiele segmentów (partitioned lock tables), co pozwala na równoległy dostęp.
- Dzięki temu eliminuje się “contention”, czyli wzajemne blokowanie się procesów przy próbie zapisu do wspólnej struktury.
- To oznacza, że wielowątkowe / wielosesyjne obciążenia (np. OLTP, duże batch insert/update, równoległe DDL) działają teraz znacznie szybciej i płynniej.
Lock Manager
- W PostgreSQL wszystkie blokady (np. na tabele, indeksy, relacje itp.) są zarządzane przez centralny Lock Manager.
- Jest on zabezpieczony przez lekkie blokady wewnętrzne (Lightweight Locks, czyli LWLock), aby zapewnić synchronizację dostępu wielu procesów.
- przy duzej liczbie blokad staje sie waski gardlem co ie objawia:
- widoczny w pg_stat_activity lub perf jako:
SELECT * FROM pg_stat_activity WHERE wait_event = 'LWLock:LockManager';
LWLock:LockManager
- albo logi typu:
LOG: process 12345 still waiting for LockManager
Co powoduje presje i contension na LockManager
- duza liczba indeksow
- partycje
- duze zrownoleglenie - wiele tranzakcji, zapytan
- wymuszenie planów generycznych (aby plan nie był rekalkulowany co zapytanie) może pogorszyć sytuację w kontekście LockManagera, bo może wymagać bardziej ogólnych mechanizmów blokad Jak przeciwdzialac:
- zmniejszenie liczby indeksów,
- przemyślane partycje (mniej, większe partie zamiast wielu codziennych),
- użycie planów przygotowanych/ unikanie ponownego planowania, ewentualne zmiany w kodzie PostgreSQL (patchy dotyczące LWLock)
max_locks_per_transaction
Parametr max_locks_per_transaction określa, ile jednostek blokad (lock entries) może posiadać jedna transakcja. Gdy za maly to blad:
ERROR: out of shared memory
HINT: You might need to increase max_locks_per_transaction.
Podnoszenie max_locks_per_transaction pogarsza performance.