Tihiroのストレスフリーな生活

少しだけ頭使って後は根性

PostgreSQLで現在のトランザクションIDを確認する。

概要

いつも通りタイトルの通りなのですが、PostgreSQLで現在のトランザクションID、つまりはxidを確認する方法についてす。

確認方法

SELECT txid_current();

で確認することができます。

ただし、psqlで実行する場合は暗黙的にトランザクションが開始されますので、上記コマンドを実行するとトランザクションIDが進んでしまいます。

postgres=# SELECT txid_current();
 txid_current
--------------
          818
(1 行)

postgres=# SELECT txid_current();
 txid_current
--------------
          819
(1 行)

↑こんな風に実行するたびに、現在のトランザクションIDが進んでしまいます。 じゃあ、どうするの、って話なのですが、BEGINしておけば進むxidを最小限に抑えられます。

postgres=# BEGIN;
BEGIN
postgres=# SELECT txid_current();
 txid_current
--------------
          820
(1 行)

postgres=# SELECT txid_current();
 txid_current
--------------
          820
(1 行)

postgres=# SELECT txid_current();
 txid_current
--------------
          820
(1 行)

postgres=# ROLLBACK;
ROLLBACK
postgres=# SELECT txid_current();
 txid_current
--------------
          821
(1 行)

とすることで、xidの進みを819→820だけに抑えることができます(残念ながらROLLBACKしても819→820→819にはなりません)。

確認して何が楽しい?

現在のトランザクションIDを確認してどうするの、っていうことですが、これはレコードのxmin、xmaxと比較するのに使います(個人的には)。

SELECT xmin, xmax, * FROM test_table

とすると、test_tableテーブルの行がもつxminとxmaxの値が表示されます。

xminはそのレコードに対して最後に更新を行なったトランザクションIDを表します(UPDATEでもxminは更新されます)。

xmaxはそのレコードに対して最後に削除処理を行なったトランザクションIDを表します(削除されていないレコードはxmaxが0です)。

また、

SELECT age(xmin), xmin FROM test_table;

とすることで、xminが現在のトランザクションIDとの差分を確認することができます。 他の行と比較することで、どっちが古い、どっちが新しい、とかいうのが分かります(ただしxidは周回するので、完璧に判断できるわけではありません)。

その他には

動作検証するときなどに、xminとかxmaxとかを確認しつつ、っていうパターンもありますよね。

まとめ

txid_current関数なのですが、名前が他のPostgreSQLシステム関数と違って覚えにくいのが難点です。が、非常に便利な関数ですのでメモしておきます。