9.6. 锁与表 #
Postgres 提供多种锁模式来控制对表中数据的并发访问。其中一些锁模式由 Postgres 在语句执行之前自动获取,另一些则供应用使用。事务中获取的所有锁模式在该事务期间一直保持。
9.6.1. 表级锁
- AccessShareLock
在被查询的表上自动获取的一种读锁模式。
只与 AccessExclusiveLock 冲突。
- RowShareLock
由
SELECT FOR UPDATE以及IN ROW SHARE MODE的LOCK TABLE语句获取。与 ExclusiveLock 和 AccessExclusiveLock 模式冲突。
- RowExclusiveLock
由
UPDATE、DELETE、INSERT以及IN ROW EXCLUSIVE MODE的LOCK TABLE语句获取。与 ShareLock、ShareRowExclusiveLock、ExclusiveLock 和 AccessExclusiveLock 模式冲突。
- ShareLock
由
CREATE INDEX以及IN SHARE MODE的LOCK TABLE语句获取。与 RowExclusiveLock、ShareRowExclusiveLock、ExclusiveLock 和 AccessExclusiveLock 模式冲突。
- ShareRowExclusiveLock
由
IN SHARE ROW EXCLUSIVE MODE的LOCK TABLE语句获取。与 RowExclusiveLock、ShareLock、ShareRowExclusiveLock、ExclusiveLock 和 AccessExclusiveLock 模式冲突。
- ExclusiveLock
由
IN EXCLUSIVE MODE的LOCK TABLE语句获取。与 RowShareLock、RowExclusiveLock、ShareLock、ShareRowExclusiveLock、ExclusiveLock 和 AccessExclusiveLock 模式冲突。
- AccessExclusiveLock
由
ALTER TABLE、DROP TABLE、VACUUM和LOCK TABLE语句获取。与所有模式冲突(AccessShareLock、RowShareLock、RowExclusiveLock、ShareLock、ShareRowExclusiveLock、ExclusiveLock 和 AccessExclusiveLock)。
注意
只有
AccessExclusiveLock 会阻塞(不带
FOR UPDATE 的)SELECT 语句。
9.6.2. 行级锁
这些锁在行被更新(或删除或标记为更新)时获取。行级锁不影响数据查询。它们只阻塞同一行的写者。
Postgres
不会在内存中保存任何关于已修改行的信息,因此一次加锁的行数没有限制。不过,锁定一行可能导致一次磁盘写;例如,SELECT FOR UPDATE 会修改被选中的行以标记它们,因此会产生磁盘写入。
除了表锁和行锁之外,还使用短期的共享/排他锁来控制对共享缓冲池中表页的读写访问。这些锁在取到或更新一个元组后立即释放。应用开发者通常不需要关心页级锁,但为完整性起见我们提一下。