

# autovacuum の実行中にテーブルのインデックスを再作成する
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.Reindexing"></a>

インデックスが破損した場合、autovacuum はテーブルの処理を続けますが失敗します。この状況で手動バキュームを試みると、次のようなエラーメッセージが表示されます。

```
postgres=>  vacuum freeze pgbench_branches;
ERROR: index "pgbench_branches_test_index" contains unexpected 
   zero page at block 30521
HINT: Please REINDEX it.
```

インデックスが破損しているときに、自動バキュームをテーブルで実行しようとすると、既に実行中の自動バキュームセッションと競合します。「[REINDEX](https://www.postgresql.org/docs/current/static/sql-reindex.html)」コマンドを発行する場合は、テーブルに対する排他ロックを取り除きます。書き込みオペレーションがブロックされ、この特定のインデックスを使用する読み込みオペレーションもブロックされます。

**autovacuum がテーブルに対して実行されているときにテーブルのインデックスを再作成するには**

1. バキュームを実行するテーブルを含むデータベースへのセッションを 2 つ開きます。2 番目のセッションで、接続が中断された場合にセッションを維持する「screen」または他のユーティリティを使用します。

1. セッション 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;
   ```

1. セッション 2 で、reindex コマンドを発行します。

   ```
   \timing on
   Timing is on.
   reindex index pgbench_branches_test_index;
   REINDEX
     Time: 9.966 ms
   ```

1. セッション 1 で、自動バキュームがプロセスをブロックしていた場合、`pg_stat_activity` で、バキュームセッションの [waiting] (待機) が「T」であることを確認できます。この場合、自動バキュームプロセスを終了します。

   ```
   SELECT pg_terminate_backend('the_pid');
   ```

   この時点で、セッションがスタートされます。このテーブルは作業リストの一番上にあると思われるため、autovacuum が即座に再開される点に注意することが重要です。

1. セッション 2 で コマンドを開始し、セッション 1 で自動バキュームプロセスを終了します。