REINDEX — インデックスを再構築する
REINDEX [ ( VERBOSE ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } name
REINDEX
は、インデックスのテーブルに保存されたデータを使用してインデックスを再構築し、古いインデックスのコピーと置き換えます。
以下にREINDEX
が使用される状況を示します。
インデックスが破損してしまい、有効なデータがなくなった場合です。
理論的には決して起こらないはずですが、実際には、ソフトウェアのバグやハードウェアの障害によりインデックスが破損することがあります。
REINDEX
はこの修復手段を提供します。
インデックスが「膨張状態」、つまり、多くの空、もしくは、ほとんど空のページを持つ状態になっている場合です。
この状況は、PostgreSQLのB-treeインデックスが特定の普通でないパターンでアクセスされた場合に起こり得ます。
REINDEX
を使って、使用されないページを取り除いた新しいインデックス作成すると、インデックスの領域消費量を減少することができます。
詳細は24.2を参照してください。
インデックスの格納パラメータ(フィルファクタなど)を変更し、この変更を確実に有効にしたい場合です。
CONCURRENTLY
オプションをつけたインデックス作成が失敗し、「無効な」インデックスが残った場合です。
こうしたインデックスは使用されませんが、REINDEX
を使用して再作成するのが便利かもしれません。
REINDEX
では同時構築ができないことに注意してください。
運用に影響を与えずにインデックスを作成するためには、インデックスを削除してからCREATE INDEX CONCURRENTLY
コマンドを再発行しなければなりません。
INDEX
指定したインデックスを再作成します。
TABLE
指定したテーブルの全インデックスを再作成します。 テーブルに2次的な「TOAST」テーブルがある場合、それについてもインデックスを再作成します。
SCHEMA
指定したスキーマのすべてのインデックスを再作成します。
このスキーマのテーブルが二次的な「TOAST」テーブルを持っている場合は、そのインデックスも再作成されます。
共有システムカタログのインデックスも処理されます。
この構文のREINDEX
はトランザクションブロックの内側で実行することはできません。
DATABASE
現在のデータベースのすべてのインデックスを再作成します。
共有システムカタログのインデックスも処理されます。
この構文のREINDEX
をトランザクションブロック内で実行することはできません。
SYSTEM
現在のデータベースのシステムカタログに対するすべてのインデックスを再作成します。
共有システムカタログのインデックスも含みます。
ユーザテーブルのインデックスは処理されません。
この構文のREINDEX
をトランザクションブロック内で実行することはできません。
name
インデックスを再作成するインデックス、テーブル、データベースの名前です。
インデックスとテーブルはスキーマ修飾可能です。
現状では、REINDEX DATABASE
とREINDEX SYSTEM
は現在のデータベースのインデックスのみを再作成することができます。
そのため、このパラメータは現在のデータベース名と一致する必要があります。
VERBOSE
各インデックスが再作成されるときに、進捗レポートを表示します。
ユーザテーブル上の特定のインデックスに破損の疑いがある場合、REINDEX INDEX
を使ってそのインデックスを再構築することもできますし、REINDEX TABLE
を使ってそのテーブルのすべてのインデックスを再構築することもできます。
システムテーブルのインデックスの破損を復旧する場合の手順はより複雑になります。
この場合、システムによって破損の可能性があるインデックス自体が使用されないようにすることが重要です
(実際は、このようなケースでは、破損したインデックスに依存していたため、サーバプロセスが起動時に強制終了してしまう可能性があります)。
安全に復旧させるには、システムカタログ検索時のインデックスの使用を禁止する-P
オプションを使用してサーバを起動しなければなりません。
考えられる方法の1つは次の方法です。まず、サーバを停止して、コマンドラインから-P
オプションを指定してシングルユーザ状態のPostgreSQLサーバを起動します。
そして、再構成する範囲に応じて、REINDEX DATABASE
、REINDEX SYSTEM
、REINDEX TABLE
、または、REINDEX INDEX
コマンドを発行します。
範囲が不明な場合は、REINDEX SYSTEM
を使用して、そのデータベースの全てのシステムインデックスを再構成してください。
その後、シングルユーザ状態のサーバセッションを停止して、通常のサーバを再起動します。
シングルユーザ状態のサーバインタフェースの操作方法についての詳細は、postgresマニュアルページを参照してください。
その他、コマンドラインで-P
を指定して通常のサーバセッションを起動することもできます。
具体的な方法は、クライアントによって異なります。
しかし、libpqベースのクライアントであれば、クライアントを起動する前に環境変数PGOPTIONS
を-P
に設定すれば実現できます。
この方法では他のクライアントを締め出す必要はありませんが、修復が終わるまで破損したデータベースへの他のユーザの接続を防止する方が良いことに注意してください。
REINDEX
は、インデックスの中身を1から作り直すという点では、インデックスを削除してから再作成する処理と似ています。
しかし、ロックに関しては異なります。
REINDEX
はインデックスの元となるテーブルの書き込みをロックしますが、読み込みはロックしません。
また、処理中のインデックスに対する排他ロックを取得するので、そのインデックスを使用する読み込みはブロックされます。
一方、DROP INDEX
は瞬間的に元となるテーブルの排他ロックを取得するので、書き込みも読み込みもブロックされます。
その後に行うCREATE INDEX
では書き込みのみをロックし、読み込みはロックしません。
インデックスは存在しないので、インデックスを使用する読み込みは発生しません。
したがって、読み込みがブロックされることはありませんが、コストが高いシーケンシャルスキャンの使用を強制されることになります。
単一インデックスまたは単一テーブルのインデックス再作成を行うには、そのインデックスまたはテーブルの所有者でなければなりません。
スキーマまたはデータベースに対するインデックス再作成を行うには、そのスキーマまたはデータベースの所有者でなければなりません。
したがって、非スーパーユーザが他のユーザが所有するテーブルのインデックスを再作成することができる場合があることに注意してください。
しかし、特別な例外として、REINDEX DATABASE
、REINDEX SCHEMA
、REINDEX SYSTEM
が非スーパーユーザにより発行された時には、そのユーザがカタログを所有している場合(そのようなことは通常はありません)を除いて、共有カタログのインデックスは飛ばされます。
もちろん、スーパーユーザは常にすべてのインデックス再作成を行うことができます。
パーティションテーブルやパーティションインデックスのインデックス再作成はサポートされていません。 その代わり、個々のパーティションで別々にインデックスを再作成できます。
単一のインデックスを再構築します。
REINDEX INDEX my_index;
テーブルmy_table
上のすべてのインデックスを再構築します。
REINDEX TABLE my_table;
システムインデックスが有効かどうかを確認することなく、あるデータベース内の全てのインデックスを再構築します。
$export PGOPTIONS="-P"
$psql broken_db
... broken_db=> REINDEX DATABASE broken_db; broken_db=> \q
標準SQLにはREINDEX
はありません。