トランザクションID
PostgreSQLでは各行のデータに対して以下の情報を記録している。
xmin: その行を挿入したトランザクションID
xmax: その行を削除または更新したトランザクションID
トランザクションIDは1から約42億(2^32)までのIDを使用可能。
理論的にはトランザクションIDが上限2^32に達する可能性があり、その場合ラップアラウンドをする。
ラップアラウンドが発生すると、次のトランザクションIDが0に戻り再度カウントされていく。
その結果、古いトランザクションIDと新しいトランザクションIDが重複する可能性がある。
これにより、データの整合性が損なわれたり、古いデータと新しいデータが誤認されるリスクが発生する。
不要なトランザクションID
PostgreSQLではトランザクションが完了するまで他のトランザクションからそのトランザクションの結果が見えないようになっている。
以下の場合はそのトランザクションで使用されたトランザクションIDは不要になる。
・行の削除: 行が削除され、その削除が他のすべてのトランザクションから見えるようになった場合
・行の更新: 行が更新されて新しいバージョンが作成され、古いバージョンが他のすべてのトランザクションから見えるようになった場合
Autovacuum
不要となったトランザクションIDを削除するため、PostgreSQLではAutovacuumが行われる。
・削除された行が他のすべてのトランザクションから見えるようになった場合、その行を物理的に削除する。
・更新された行の古いバージョンが他のすべてのトランザクションから見えるようになった場合、その古いバージョンを物理的に削除する
これにより、不要なトランザクションIDが解放される。
Freeze
非常に古いトランザクションIDを特別な「Freeze状態」に変更するプロセス。FreezeされたトランザクションIDはカウントされず、新しいトランザクションIDのラップアラウンドの影響を受けないため、ラップアラウンドのリスクを減少させることができる。
参考
https://aws.amazon.com/jp/blogs/news/understanding-autovacuum-in-amazon-rds-for-postgresql-environments/
https://www.postgresql.jp/document/16/html/runtime-config-autovacuum.html