2. プロセスとメモリー
3.7 トランザクション ID の周回問題
ルに対してパラメータautovacuum_freeze_max_age - vacuum_freeze_min_ageで計算さ れる数のトランザクションが発生すると、自動VACUUMが無効でもVACUUM処理が発 生します。
自動VACUUMは対象ブロックをVisibility Mapを使って発見しますが、更新されなか
ったブロックに古いトランザクションIDが残っていても気づかないことになります。この ため、パラメータvacuum_freeze_table_age で指定されたトランザクション数が実行され ると、Visibility Mapを無視して全ブロックがチェックされます。
各 テ ー ブ ル の フ リ ー ズ 対 象 と な る ト ラ ン ザ ク シ ョ ン ID は 、pg_class ビ ュ ー の
relfrozenxid列で定義されています。この列はテーブル内のタプルのXMIN の最小値です
(FrozenXIDを除く)。またpg_classビューのrelfrozenxidの最小値がpg_databaseビュ ーのdatfrozenxid列で確認できます。
□ 自動VACUUM処理が失敗した場合
何等かの原因でFREEZE処理が行われなかった場合、トランザクションIDの周回まで
に1,000万を切ると以下のメッセージが出力されます。
WARNING: database "データベース名" must be vacuumed within 残り数 transactions HINT: To avoid a database shutdown, execute a database-wide VACUUM in "データベ ース名".
更に100万トランザクションを切ると、以下のログが出力され、システムは停止します。
ERROR: database is not accepting commands to avoid wraparound data loss in database "データベース名"
HINT: Stop the postmaster and use a standalone backend to VACUUM in "データベー ス名".
このような状態に陥ったデータベースはスタンドアロン・モードで起動し、VACUUM処 理を行います。下記の例ではpostgresデータベースに対してVACUUM処理を実行してい ます。
例 67 スタンドアロン・モードによる起動とVACUUM
3.7.2 FREEZE 処理に関するパラメータ
トランザクションIDのFREEZE動作に関するパラメータは以下の通りです。
□ autovacuum_freeze_max_age
トランザクションIDの周回を防ぐためにpg_class.relfrozenxidが到達できる最大の年代
(age)を指定します。自動VACUUMが無効の場合でも、VACUUMワーカー・プロセス が起動します。デフォルト値は2億(200,000,000)です。最小値は1億(100,000,000)、 最大値は20億(2,000,000,000)です。
□ vacuum_freeze_min_age
VACUUMがテーブルスキャン時にトランザクション IDをFrozenXIDに置き換えるカ
ットオフ年代を指定します。デフォルト値は 5,000 万(50,000,000)です。値は 0 から autovacuum_freeze_max_ageの50%までの値を指定できます。
□ vacuum_freeze_table_age
テーブルのpg_class.relfrozenxid がこの値で指定した時期に到達すると、VACUUM は テーブル全体の走査を行います。通常のVACUUMはVisibility Mapからガベージの有無 を検索しますが、その場合古いトランザクションIDを持つタプルが発見できない恐れがあ ります。このパラメータの時期に到達すると、VACUUM処理はVisibility Mapを無視して、
テーブル全体をスキャンします。デフォルト値は1.5億(150,000,000)です。値は0から 10億(1,000,000,000)またはautovacuum_freeze_max_age の95%までの値を指定でき ます。
$ postgres --single -D data postgres
PostgreSQL stand-alone backend 9.4beta1 backend> VACUUM
backend>