每当事务开始时,事务管理器就会为其分配一个称为事务标识(transaction id, txid) 的唯一标识符。 PostgreSQL的txid
是一个32位无符号整数,总取值约42亿。在事务启动后执行内置的txid_current()
函数,即可获取当前事务的txid
,如下所示。
testdb=# BEGIN;
BEGIN
testdb=# SELECT txid_current();
txid_current
--------------
100
(1 row)
PostgreSQL保留以下三个特殊txid
:
- 0 表示无效(Invalid) 的
txid
。 - 1 表示初始启动(Bootstrap) 的
txid
,仅用于数据库集群的初始化过程。 - 2 表示冻结(Frozen) 的
txid
,详情参考第5.10.1节。
txid
可以相互比较大小。例如对于txid=100
的事务,大于100的txid
属于“未来”,且对于txid=100
的事务而言都是不可见(invisible) 的;小于100的txid
属于“过去”,且对该事务可见,如图5.1(a)所示。
图5.1 PostgreSQL中的事务标识
因为txid
在逻辑上是无限的,而实际系统中的txid
空间不足(4字节取值空间约42亿),因此PostgreSQL将txid
空间视为一个环。对于某个特定的txid
,其前约21亿个txid
属于过去,而其后约21亿个txid
属于未来。如图5.1(b)所示。
所谓的txid
回卷问题将在 5.10 所需的维护进程 中介绍。
请注意,
txid
并非是在BEGIN
命令执行时分配的。在PostgreSQL中,当执行BEGIN
命令后的第一条命令时,事务管理器才会分配txid
,并真正启动其事务。