如何解释 PostgreSQL txid_current() 值
How to interpret PosgreSQL txid_current() value
我有以下 psql 语句:
假设:初始 txid:a
select txid_current();
----------------------
a+1
begin;
insert into tab( v1,v2);
insert into tab (v3,v4);
commit;
select txid_current();
----------------------
a+3
为什么我看到交易 ID 是 a+3 不应该是 a+2?
txid_current 是如何工作的?
有没有什么有效的方法可以让我只return当前的 txid 而没有额外的增量?
要理解的要点:
一切都在交易中。如果您没有使用 BEGIN
和 COMMIT
(或 ROLLBACK
)显式创建一个,那么系统会为您创建一个仅针对该语句的。
只读 SELECT
s 不会获得完整的交易 ID,它们只会获得虚拟交易 ID。因此,即使它是一个交易,SELECT 1;
或任何不会增加交易 ID 计数器的东西。
调用txid_current()
强制分配事务 ID(如果尚未分配的话)。因此,只读事务现在将有一个事务 ID,而以前是没有的。
当然,txids也是跨session分配的。实际上,如果数据库繁忙,您上面的示例可能会得到 txid 的 a+1 和 a+429。
在应用程序级别对任何事物使用事务 ID 通常是不明智的。特别是:
将xmin
和xmax
视为内部系统级字段,将txid_current()
的结果视为无意义的数值。
关于 xid 正确和不正确使用的详细信息
尤其是你不应该:
- 通过数值比较 xid 以得出有关其排序的任何类型的结论;
- 添加或减去交易 ID;
- 排序交易 ID;
- 增加或减少交易 ID
- 将 32 位
xid
类型字段与 64 位 bigint
纪元扩展 xid 进行比较,即使相等。
所以从应用程序的角度来看,xid 既不是单调的也不是有序的。
您可以安全:
- 比较两个 64 位历元扩展 xid 是否相等;和
- 将 xid 传递给
txid_status(...)
以及记录为采用 xid 的其他函数
注意:PostgreSQL 使用像 xid
类型这样的 32 位窄 xid,以及通常表示为 bigint
的 64 位纪元扩展 xid,就像 txid_current()
。比较这些是否相等通常似乎适用于新的数据库安装,但一旦第一个纪元环绕发生,它们将不再相等。 Pg 甚至没有给你一个简单的方法来查看 SQL 级别的 xid 纪元;你必须:
select (txid_current() >> 32) AS xid_epoch;
获取txid_current()
报告的纪元扩展xid的高32位。
所以...无论您尝试做什么,交易 ID 都可能不是正确的方法。
我有以下 psql 语句:
假设:初始 txid:a
select txid_current();
----------------------
a+1
begin;
insert into tab( v1,v2);
insert into tab (v3,v4);
commit;
select txid_current();
----------------------
a+3
为什么我看到交易 ID 是 a+3 不应该是 a+2?
txid_current 是如何工作的?
有没有什么有效的方法可以让我只return当前的 txid 而没有额外的增量?
要理解的要点:
一切都在交易中。如果您没有使用
BEGIN
和COMMIT
(或ROLLBACK
)显式创建一个,那么系统会为您创建一个仅针对该语句的。只读
SELECT
s 不会获得完整的交易 ID,它们只会获得虚拟交易 ID。因此,即使它是一个交易,SELECT 1;
或任何不会增加交易 ID 计数器的东西。调用
txid_current()
强制分配事务 ID(如果尚未分配的话)。因此,只读事务现在将有一个事务 ID,而以前是没有的。
当然,txids也是跨session分配的。实际上,如果数据库繁忙,您上面的示例可能会得到 txid 的 a+1 和 a+429。
在应用程序级别对任何事物使用事务 ID 通常是不明智的。特别是:
将xmin
和xmax
视为内部系统级字段,将txid_current()
的结果视为无意义的数值。
关于 xid 正确和不正确使用的详细信息
尤其是你不应该:
- 通过数值比较 xid 以得出有关其排序的任何类型的结论;
- 添加或减去交易 ID;
- 排序交易 ID;
- 增加或减少交易 ID
- 将 32 位
xid
类型字段与 64 位bigint
纪元扩展 xid 进行比较,即使相等。
所以从应用程序的角度来看,xid 既不是单调的也不是有序的。
您可以安全:
- 比较两个 64 位历元扩展 xid 是否相等;和
- 将 xid 传递给
txid_status(...)
以及记录为采用 xid 的其他函数
注意:PostgreSQL 使用像 xid
类型这样的 32 位窄 xid,以及通常表示为 bigint
的 64 位纪元扩展 xid,就像 txid_current()
。比较这些是否相等通常似乎适用于新的数据库安装,但一旦第一个纪元环绕发生,它们将不再相等。 Pg 甚至没有给你一个简单的方法来查看 SQL 级别的 xid 纪元;你必须:
select (txid_current() >> 32) AS xid_epoch;
获取txid_current()
报告的纪元扩展xid的高32位。
所以...无论您尝试做什么,交易 ID 都可能不是正确的方法。