happy_boy 发表于 2016-12-21 10:38:12

PostgreSQL spin 与 lwlock-jesselyu

  在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等强相关。与数据库中表存在一一映射关系。
页: [1]
查看完整版本: PostgreSQL spin 与 lwlock-jesselyu