像其它数据库一样,PostgreSQL数据库不仅有表级别的锁,同时也有行级别的锁。行锁对于提高系统的并行度至关重要。那么PostgreSQL是如何实现行锁的呢?
PostgreSQL获取行锁的大致分为以下两个阶段:
1.获取buffer page级别的锁
这是一个buffer content锁,不是单纯的buffer pin,当然buffer pin的次数肯定会增加。buffer content锁分为share和exclusive两种。”share”是共享锁,
一般的读操作,获取的就是share锁。”exclusive”是排它锁,对记录的修改,增加,删除等需要获取此类锁。
另外Buffer page又分为两种,分别是local和shared。backend进程独有的buffer是不需要锁的,因为它只被本backend进程独享,是local的。如临时表等。
我们通常需要加锁处理都是针对shared类型的buffer,不同进程之间对buffer page的操作需要通过锁机制来保障。
在对一个buffer page进行加锁前,需要进行可性性判断。即本条记录是否是“HeapTupleInvisible”。如果是invisible的,是不能加锁,这也是事务隔离的需要。
2.设置行锁标志位
行锁的实现比较复杂,我们不可能把所有需要上锁的记录都放到内存的lock table中,因为有些情况下,涉及到的记录非常多。为了解决这个问题,通常只在
tuple的header中设置标记为来标识此行记录已经被锁。这两个关键的标记为xmax和infomask。”xmax”放置当前事务的xid,“infomask”放置flag信息。</