2020-09-26 05:48:45
PostgreSQL锁机制的核心目标是确保并发事务的一致性与隔离性,同时平衡性能与数据完整性。通过细粒度锁(如行级锁)提升并发能力,粗粒度锁(如表级锁)简化控制逻辑,避免过度阻塞。
二、锁的分类与行为1. 行级锁(Row-Level Locks)
FOR UPDATE:获取行排他锁(Exclusive Lock),阻止其他事务修改或锁定该行。
FOR SHARE:获取行共享锁(Share Lock),允许其他事务读但阻止写。
2. 表级锁(Table-Level Locks)
ACCESS EXCLUSIVE:独占表,阻止所有并发访问(如ALTER TABLE、DROP TABLE)。
ROW EXCLUSIVE:允许读,阻止其他写操作(如INSERT、UPDATE、DELETE)。
SHARE UPDATE EXCLUSIVE:冲突于所有写锁(如VACUUM FULL)。
3. 意向锁(Intention Locks)
INTENTION SHARE (IS):表示将获取行共享锁。
INTENTION EXCLUSIVE (IX):表示将获取行排他锁。
后台进程deadlock detector定期扫描锁等待图(Wait-for Graph),检测循环依赖。
触发频率由deadlock_timeout参数控制(默认1秒)。
缩短事务时长,减少锁持有时间。
避免固定顺序加锁(如按表名排序操作顺序)。
开启log_lock_waits记录长时间等待(阈值由deadlock_timeout定义)。
pg_stat_activity:查看锁持有事务的SQL与状态。
pg_locks:分析锁类型、模式及依赖关系。
常见原因:全表扫描导致行锁扩散为表锁。
解决方案:优化索引,避免无索引条件查询。
避免长事务,拆分复杂操作为短事务。
对多表操作按固定顺序加锁(如先库存表后订单表)。
高并发场景优先行级锁(如OLTP系统)。
批量操作或DDL使用表级锁(如TRUNCATE)。
确保查询使用索引,防止全表扫描导致锁升级。
定期分析pg_locks与pg_stat_activity,识别热点锁。
通过日志定位死锁根源,优化事务逻辑。
1. 行级锁的显式触发方式有哪些?
2. 表级锁ACCESS EXCLUSIVE的典型应用场景是什么?
3. 意向锁的设计目的是什么?
4. 共享锁与排他锁的核心区别是什么?
5. 如何通过日志定位锁等待问题?
6. 为什么FOR UPDATE比普通SELECT影响并发性能?
7. 如何避免跨事务的锁顺序冲突导致死锁?
PostgreSQL锁机制通过分层粒度(行级、表级、意向锁)实现并发控制与性能平衡,核心逻辑包括:
实践中需结合业务场景选择锁粒度,优化事务逻辑与索引设计,确保数据一致性的同时最大化并发性能。