深入解析 PostgreSQL 系列之并发控制与事务机制

2020-06-17 00:00:00 更新 命令 事务 状态 快照

深入解析 PostgreSQL 系列整理自 The Internals of PostgreSQL 等系列文章,从碎片化地阅读到体系化地学习,感觉对数据库有了更深入地了解;触类旁通,相互印证,也是有利于掌握 MySQL 等其他的关系型数据库或者 NoSQL 数据库。

深入解析 PostgreSQL 系列之并发控制与事务机制

并发控制旨在针对数据库中对事务并行的场景,保证 ACID 中的一致性(Consistency)与隔离(Isolation)。数据库技术中主流的三种并发控制技术分别是: Multi-version Concurrency Control (MVCC), Strict Two-Phase Locking (S2PL), 以及 Optimistic Concurrency Control (OCC),每种技术也都有很多的变种。在 MVCC 中,每次写操作都会在旧的版本之上创建新的版本,并且会保留旧的版本。当某个事务需要读取数据时,数据库系统会从所有的版本中选取出符合该事务隔离级别要求的版本。MVCC 的大优势在于读并不会阻塞写,写也不会阻塞读;而像 S2PL 这样的系统,写事务会事先获取到排他锁,从而会阻塞读事务。

PostgreSQL 以及 Oracle 等 RDBMS 实际使用了所谓的 Snapshot Isolation(SI)这个 MVCC 技术的变种。Oracle 引入了额外的 Rollback Segments,当写入新的数据时,老版本的数据会被写入到 Rollback Segment 中,随后再被覆写到实际的数据块。PostgreSQL 则是使用了相对简单的实现方式,新的数据对象会被直接插入到关联的 Table Page 中;而在读取表数据的时候,PostgreSQL 会通过可见性检测规则(Visibility Check Rules)来选择合适的版本。

SI 能够避免 ANSI SQL-92 标准中定义的三个反常现象:脏读(Dirty Reads),不可重复读(Non-Repeatable Reads)以及幻读(Phantom Reads);在 9.1 版本后引入的 Serializable Snapshot Isolation(SSI)则能够提供真正的顺序读写的能力。

Tuple 结构

Transaction ID

当某个事务开启时,PostgreSQL 内置的 Transaction Manager 会为它分配的 Transaction ID(txid);txid 是 32 位无类型整型值,可以通过 txid_current() 函数来获取当前的 txid:

testdb=# BEGIN;
BEGIN
testdb=# SELECT txid_current();
 txid_current
--------------
          100
(1 row)

相关文章