|
在PostgreSQL 中,内存锁大致可以分为spin lock, lwlock以及Lock。
1.spin lock
就是自旋锁,实现的成本最低,一般使用TAS(test and set)来实现,而TAS操作,通常由硬件来实现内存操作。没有队列的概念。
因此速度是最快的。通常只有exlusive一种模式,要么得到,要么不断spin-》sleep-》spin。详细内容见可我另外一篇文章“TAS 指令与PostgreSQL spin lock“。
PG中,s_lock.h中定义的tas指令操作:
从上面的asm 嵌入指令中,可以看出汇编指令的操作也就是简单的比较与置位。实现简单快速。
2.lwlock
也就是PG中所讲的轻量级锁(Light-weight lock)。这个锁一般由spin lock来保护。lwlock比spin lock多一种共享模式。
源码中定义:
其中 slock_t 类型的mutex就是用来保护LWLOCK的,另外多了shared模式。因此,从实现上比spin重了点。但是跟lock比,还是比较轻量级的,这也是为什么有了Light-Weight Lock的名称的原因。
PG中默认预先定义了许多LWLOCK,通常是跟共享内存的操作相关的。比较著名的如:
BufFreelistLock:用来保护buffer pool的freelist
WALInsertLock,WALWriteLock:用来保护WAL
ControlFileLock:保护控制文件的写
CheckpointLock:保护检查点
3.lock
是PG中重量级锁,是low-level锁,与表和事务相关。为application级别锁。这就是通常我们讲的表锁,行锁等。定义如下:
NoLock 0 /* NoLock is not a lock mode, but a flag value meaning "don't get a lock" */
AccessShareLock 1 /* SELECT */
RowShareLock 2 /* SELECT FOR UPDATE/FOR SHARE */
RowExclusiveLock 3 /* INSERT, UPDATE, DELETE */
ShareUpdateExclusiveLock 4 /* VACUUM (non-FULL),ANALYZE, CREATE * INDEX CONCURRENTLY */
ShareLock 5 /* CREATE INDEX (WITHOUT CONCURRENTLY) */
ShareRowExclusiveLock 6 /* like EXCLUSIVE MODE, but allows ROW * SHARE */
ExclusiveLock 7 /* blocks ROW SHARE/SELECT...FOR * UPDATE */
AccessExclusiveLock 8 /*> lock的获取与释放,都有队列来维护。源码定义如下:
LOCKTAG,与PG中的数据库,relation等强相关。与数据库中表存在一一映射关系。 |
|
|