← ClaudeAtlas

lockinglisted

Pick a PostgreSQL backend lock primitive (atomic / spinlock / LWLock / heavyweight / predicate / buffer-pin-content) or debug a lock-ordering bug, silent LWLock hang, deadlock-detector report, or a multixact / tuple-lock interaction — the six-layer PG lock taxonomy in operational form. Covers `pg_atomic_u32 / u64` ordering + memory barriers, `SpinLockAcquire / SpinLockRelease` (with the "no calls / no ereport / no CHECK_FOR_INTERRUPTS" rules), `LWLockAcquire LW_SHARED / LW_EXCLUSIVE` and tranches (lwlocklist.h + wait_event_names.txt), heavyweight `LockAcquire` / `LockRelationOid` / `LOCKTAG_*`, predicate (SSI) locks, buffer pin / content locks, the `BufferMapping / LockManager / PredicateLockManager` partition rank rules, multi-XID `HEAP_XMAX_IS_MULTI` interaction with `FOR UPDATE / FOR KEY SHARE`, parallel-worker lock-group semantics, and the lldb-attach recipe for silent-LWLock-deadlock diagnosis. **Use this skill proactively whenever the user is writing or reviewing C in `src/backend` or `dev/src/backend`
matejformanek/postgres-claude · ★ 0 · AI & Automation · score 70
Install: claude install-skill matejformanek/postgres-claude
# Locking — operational checklist Companion to `knowledge/idioms/locking-overview.md`. Use this when you are about to **write code that touches shared memory** in `src/backend/`. Stop and read the overview first if you have not internalized the six-layer taxonomy (atomics → spinlocks → LWLocks → heavyweight → predicate → row). ## 0. Triage — is shared state actually involved? Touching any of these means yes: - A struct in `*Shmem*` allocation, anything reachable from `MainLWLockArray`, anything in `BufferDesc`/`PGPROC`/SLRU/`procArray`. - Files on disk (pages flushed need to follow WAL-before-data). - A relation, tuple, transaction id, or advisory key — these need heavyweight locks. If everything you touch is on the backend's own stack/heap/`MemoryContext`, you don't need a lock at all. Per-backend `MemoryContext`s are *not* shared. ## 1. Decision tree ``` What are you protecting? │ ├─ A user-visible object (table / row / xact / advisory key)? │ → Heavyweight lock via LockAcquire(LOCKTAG_*, mode, ...). │ Pick the *weakest* mode in the conflict matrix that still excludes the bad │ concurrency. See knowledge/idioms/locking-overview.md §1.4. │ ├─ A read in a serializable transaction that needs to be "remembered" so │ later writes can detect rw-conflict? │ → PredicateLockTuple/Page/Relation (only meaningful at SERIALIZABLE). │ ├─ A single word (counter, flag, packed state) on the hot path, where the │ whole update fits in one CAS / fetch-and-add? │ → pg_atomic_*.