系列文章翻译自 https://habr.com/en/company/postgrespro/blog/500714/

之前的系列文章分别介绍了隔离和并发控制,以及日志。这个系列,我们介绍锁。包括以下文章:

  1. 表锁
  2. 行锁
  3. 其他对象上的锁和谓词锁
  4. 内存中的锁

image.png

概述

PostgreSQL 中有各种各样的技术用于 “锁住” 一些东西。因此,我将首先以较笼统的方式解释,为什么需要锁,所得可用类型以及它们之间的区别。然后,在搞清楚 PostgreSQL 中用了哪种类型的锁。最后介绍 PostgreSQL 中不同类型的锁。

锁用于控制对共享资源的并发访问。所谓并发,即多个进程同时访问,这些进程本身可以使并行运行或者分时串行的。没有并发,就不需要锁。

在访问资源之前,进程必须获取与该资源关联的锁。在较底层来看,锁是共享内存中的区域,该区域中有标识用于说明锁是否释放或者获取,可能还有一些其他信息,如进程号,获取时间等。

注意,共享内存中的区域本身是允许并发访问的资源。如果再往更底层看,为了规范访问,OS 提供了专门的同步原语(例如信号量或互斥量)。他们的目的是确保访问共享资源的代码仅在一个进程中使用。在最底层,这些原语是通过原子处理器指令(如 test-and-set 或 compare-and-swap)实现的。

当进程不再需要资源时,则释放锁使得其他进程可以使用它。

当然,有时可能无法获取到锁:资源正在被其他进程使用。然后,该进程要么在队列中等待,要么在一段时间后重复尝试获取锁。无论如何,该进程需要等待资源释放。

有时可以使用其他非阻塞策略。例如,在某些情况下,多版本并发控制允许多个进程同时使用不同版本的数据,而不会互相阻塞。

通常,对于保护的资源,我们指的是我们可以明确标识并将锁地址与其关联的内容。如数据库系统中的数据页(由文件名和文件位置标识),或者表中的行(由数据页和其中的偏移量标识)。