autovacuum の実行中にテーブルのインデックスを再作成する
インデックスが破損した場合、autovacuum はテーブルの処理を続けますが失敗します。この状況で手動バキュームを試みると、次のようなエラーメッセージが表示されます。
postgres=>
vacuum freeze pgbench_branches;
ERROR: index "pgbench_branches_test_index" contains unexpected zero page at block 30521 HINT: Please REINDEX it.
インデックスが破損しているときに、自動バキュームをテーブルで実行しようとすると、既に実行中の自動バキュームセッションと競合します。「REINDEX
autovacuum がテーブルに対して実行されているときにテーブルのインデックスを再作成するには
-
バキュームを実行するテーブルを含むデータベースへのセッションを 2 つ開きます。2 番目のセッションで、接続が中断された場合にセッションを維持する「screen」または他のユーティリティを使用します。
-
セッション 1 で、テーブルを実行している autovacuum セッションの PID を取得します。
次のクエリを実行し、autovacuum セッションの PID を取得します。
SELECT datname, usename, pid, current_timestamp - xact_start AS xact_runtime, query FROM pg_stat_activity WHERE upper(query) like '%VACUUM%' ORDER BY xact_start;
-
セッション 2 で、reindex コマンドを発行します。
\timing on
Timing is on.
reindex index pgbench_branches_test_index;
REINDEX Time: 9.966 ms
-
セッション 1 で、自動バキュームがプロセスをブロックしていた場合、
pg_stat_activity
で、バキュームセッションの [waiting] (待機) が「T」であることを確認できます。この場合、自動バキュームプロセスを終了します。SELECT pg_terminate_backend('the_pid');
この時点で、セッションがスタートされます。このテーブルは作業リストの一番上にあると思われるため、autovacuum が即座に再開される点に注意することが重要です。
-
セッション 2 で コマンドを開始し、セッション 1 で自動バキュームプロセスを終了します。