概述

假如,2个会话,并发写入数据:

BEGIN;
INSERT INTO t1 VALUES(1, 'data1');
COMMIT;

BEGIN;
INSERT INTO t1 VALUES(1, 'data2');
COMMIT;

加锁逻辑:

exec_simple_query
    pg_parse_query
    pg_analyze_and_rewrite
    pg_plan_queries
    PortalStart
    PortalRun
        PortalRunMulti
            ProcessQuery
                ExecutorStart
                    standard_ExecutorStart
                        InitPlan
                            ExecInitNode
                                ExecInitModifyTable
                                    ExecInitResultRelation
                                        ExecGetRangeTableRelation
                                            table_open(relation, 'RowExclusiveLock') # 8级锁,行级排他锁
                                                relation_open
                                                    LockRelationOid
                                                        LockAcquire
                ExecutorRun
                    standard_ExecutorRun
                        ExecutePlan
                            ...
                                ExecInsert
                                    table_tuple_insert
                                        heapam_tuple_insert
                                            heap_insert
                                                RelationGetBufferForTuple
                                                    LockBuffer
                                                        LWLockAcquire(buffer, 'LW_EXCLUSIVE') # 读写锁
                                                RelationPutHeapTuple
                                                log_heap_insert
  • 锁

  • HWLock

    • 8级
    • relation, index, buffer
    • 死锁检测
  • LWLocks

    • buffer
  • SpinLock

  • PresicateLock

HWLock

锁取值操作
AccessShareLock1SELECT
RowShareLock2SELECT FOR UPDATE/SHARE
RowExclusiveLock3INSERT/UPDATE/DELETE
ShareUpdateExclusiveLock4VACUUM/ANALYZE/CRATE INDEX CONCURRENTLY
ShareLock5CREATE INDEX
ShareRowExclusiveLock6row share
ExclusiveLock7block ROW SHARE/SELECT FOR UPDATE
AccessExclusiveLock8ALTER TABLE/DROP TABLE/VACUUM FULL
LockRelationOid
    LockAcquireExtended
        hash_search

所有进程共享

LWLocks

类似信号量

  • LW_SHARED
  • LW_EXCLUSIVE
LWLockAcquire
目标工具/方法
查看当前所有 heavyweight locksSELECT * FROM pg_locks;
查看 LWLock 等待统计SELECT * FROM pg_stat_activity WHERE wait_event_type = 'LWLock';
查看 LWLock 累计统计SELECT * FROM pg_stat_lwlocks; (PG16 新增)
跟踪锁获取/释放GDB 断点 LockAcquireExtended, LWLockAcquire
分析死锁日志 deadlock detected + pg_locks 快照
观察 SSI 谓词锁debug_parallel_query = off + GDB PredicateLockTuple