了解 postgres 中的 virtualxid 事务类型
Understanding the virtualxid transaction type in postgres
我正在尝试了解 postgres 中的锁,这是我到目前为止所了解的内容。
- pg_locks包含锁定信息
- postgres 中的所有语句都在 t运行saction 中运行 explicit/implicit。 (Postgres 9.0 高性能)
根据我的理解,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
我正在尝试了解 postgres 中的锁,这是我到目前为止所了解的内容。
- pg_locks包含锁定信息
- postgres 中的所有语句都在 t运行saction 中运行 explicit/implicit。 (Postgres 9.0 高性能)
根据我的理解,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