トランザクションIDラップアラウンド後にxminとtxid_current()を比較する方法は?


12

通常の列に加えて、Postgresテーブルにはさまざまなシステム列があります。そのうちの1つはxmin、行の作成に使用されるトランザクションIDを格納します。そのデータ型はxid、ある時点で折り返す4バイトの整数です(つまり、必ずしも一意ではありません)。この関数txid_current()は、現在のトランザクションIDを返しますbigintが、「インストール中にラップしないように「エポック」カウンターで拡張されるため」として、マニュアルを引用します

トランザクションのラップアラウンドがまだ発生していない場合、両方の値が一致しているようです:

# CREATE TABLE test (label text);
CREATE TABLE
# INSERT INTO test VALUES ('test') RETURNING txid_current();
 txid_current 
--------------
   674500
(1 row)
INSERT 0 1
# SELECT xmin FROM test;
  xmin  
--------
 674500
(1 row)

しかし、私は疑問に思う:これらの2つの値は常に同等ですか?私の知る限り、txid_current()トランザクションIDのラップアラウンド(最大2 ^ 32トランザクション)後も一意の値を配信し続けxmin、ゼロから開始します。これは、両方がその時点で異なる値を返し始めることを意味しますか?

そして、これが当てはまる場合xidtxid_current()結果を規則的に抽出xminして、テーブル内のエントリと一致するようにする方法はありますか(たとえばtxid_current()、整数へのキャスト)。

編集:トランザクションIDのラップアラウンドの後、2 ^ 32トランザクションのかなり前に起こる可能性が非常に高いことを気にかけていることを明確にします。コメントでこれを指摘してくれたDanielVéritéに感謝します。


1
2 ^ 32ラップアラウンドのかなり前にシステムがon行VACUUM FREEZEを上書きするという事実を無視していますxmin。テーマの概要については、「タプルをオフにする」をご覧ください。
ダニエルベリテ

確かに、私はこの事実を質問から除外しました。指摘してくれてありがとう。そして実際、凍結は2 ^ 32よりもずっと前に起こります。ただし、古いものxminが凍結されたとしても、その質問はまだxmin実行されたものと比較して新しい(通常の)ものであることに変わりありませんtxid_current()
トムカ

1
ラップアラウンドまで1ミリオン未満のトランザクションが残っている場合、PostgreSQLがシャットダウンすることに注意してください。
user103153

回答:


5

追加されたエポックを削除しての値と一致させることができますxmin。つまり、integerから4バイトを抽出しbigintます。以来xminタイプであるxid(!署名)とではないinteger、我々は比較text代わり表現を:

SELECT * FROM test
WHERE  xmin::text = (txid_current() % (2^32)::bigint)::text;

詳細な説明:

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.