了解 postgres 中的 virtualxid 事务类型

Understanding the virtualxid transaction type in postgres

我正在尝试了解 postgres 中的锁,这是我到目前为止所了解的内容。

根据我的理解,virtualxids 不是真正的 t运行saction,而 t运行sactionidxid 表示 t运行saction。

当我简单连接到 psql shell 并查询 pg_locks table 时,那里已经存在一个 virtualxid。

我没有发起 t运行saction 或 运行 查询,那么为什么要创建这个 virtualxid?是因为这个连接以后可能会发起t运行saction吗?

我在这里错过了什么?

只要您查询 pg_locks,您实际上 运行 查询并因此开始交易。例如,它需要在 pg_locks 上获取 AccessShareLock。这就是分配virtualxid的原因。

但是虚拟交易 ID "free" 与真实交易 ID 完全不同。 Virtualxid 是后端本地的(它由后端编号加上一些序号组成)。而真正的交易id是系统范围的32位数字,所以当计数器回绕到零时就有回绕的机会。 Special action 必须采取措施以防止系统在那一刻发生故障,因此 PostgreSQL 不愿意在实际需要之前分配真正的事务 ID。

连接不会创建事务,但如果会话还没有当前打开的事务,则发出 select * from pg_locks 会隐式创建事务。 这是您在问题中引用的规则:postgres 中的所有语句都在事务内部运行 explicit/implicit

查询 select * from pg_locks 不能是中立的观察者,因为它需要自己使用一个事务并锁定 pg_locks。因此,此 select 将始终报告 至少 两个条目,如下例所示:

test=> \x
test=> SELECT relation::regclass AS relname, * FROM pg_locks;

-[ RECORD 1 ]------+----------------
relname            | pg_locks
locktype           | relation
database           | 113270
relation           | 11000
page               | 
tuple              | 
virtualxid         | 
transactionid      | 
classid            | 
objid              | 
objsubid           | 
virtualtransaction | 2/5789
pid                | 31376
mode               | AccessShareLock
granted            | t
-[ RECORD 2 ]------+----------------
relname            | 
locktype           | virtualxid
database           | 
relation           | 
page               | 
tuple              | 
virtualxid         | 2/5789
transactionid      | 
classid            | 
objid              | 
objsubid           | 
virtualtransaction | 2/5789
pid                | 31376
mode               | ExclusiveLock
granted            | t