REINDEXは、インデックスのテーブルに保存されたデータを使用してインデックスを再構築し、古いインデックスのコピーと置き換えます。 以下にREINDEXが使用される状況を示します。
インデックスが破損してしまい、有効なデータがなくなった場合です。 理論的には決して起こらないはずですが、実際には、ソフトウェアのバグやハードウェアの障害によりインデックスが破損することがあります。 REINDEXはこの修復手段を提供します。
インデックスが"膨張状態"、つまり、多くの空、もしくは、ほとんど空のページを持つ状態になっている場合です。 この状況は、PostgreSQLのB-treeインデックスが特定のパターンでアクセスされた場合に起こり得ます。 REINDEXを使って、使用されないページを取り除いた新しいインデックス作成すると、インデックスの領域消費量を減少することができます。 詳細は項22.2を参照してください。
インデックスの格納パラメータ(fillファクタなど)を変更し、この変更が有効かどうかを確認したい場合です。
CONCURRENTLYオプションをつけたインデックス作成が失敗し、"無効な"インデックスが残った場合です。 こうしたインデックスは使用されませんが、REINDEXを使用して簡単に再作成することができます。 REINDEXでは同時構築ができないことに注意してください。 運用に影響を与えずにインデックスを作成するためには、インデックスを削除してからCREATE INDEX CONCURRENTLYコマンドを再発行しなければなりません。
指定したインデックスを再作成します。
指定したテーブルの全インデックスを再作成します。 テーブルに2次的な"TOAST"テーブルがあっても、同様にインデックスを再作成します。
現在のデータベースのすべてのシステムインデックスを再作成します。 また、スタンドアロンモード(後述)以外のモードでは、共有システムカタログのインデックスは処理されません。 この構文のREINDEXをトランザクションブロック内で実行することはできません。
現在のデータベースのすべてのシステムカタログのインデックスを再作成します。 ユーザテーブルのインデックスは処理されません。 また、スタンドアロンモード(後述)以外のモードでは、共有システムカタログのインデックスは処理されません。 この構文のREINDEXをトランザクションブロック内で実行することはできません。
インデックスを再作成するインデックス、テーブル、データベースの名前です。 インデックスとテーブルはスキーマで修飾可能です。 現状では、REINDEX DATABASEとREINDEX SYSTEMは現在のデータベースのインデックスのみを再作成することができます。 そのため、このパラメータは現在のデータベース名と一致する必要があります。
このオプションは廃止されました。 指定されても無視されます。
ユーザテーブル上の特定のインデックスに破損の疑いがある場合、そのインデックスを再構築してください。 テーブル上の全てのインデックスに破損の疑いがある場合は、REINDEX INDEXかREINDEX TABLEを使用してください。
システムテーブルのインデックスの破損を復旧する場合の手順はより複雑になります。 この場合、システムによって破損の可能性があるインデックス自体が使用されないようにすることが重要です (実際は、このようなケースでは、破損したインデックスに依存していたため、サーバプロセスが起動時に強制終了してしまう可能性があります)。 安全に復旧させるには、システムカタログ検索時のインデックスの使用を禁止する-Pオプションを使用してサーバを起動しなければなりません。
考えられる方法の1つは次の方法です。まず、サーバを停止して、コマンドラインから-Pオプションを指定してシングルユーザ状態のPostgreSQLサーバを起動します。 そして、再構成する範囲に応じて、REINDEX DATABASE、REINDEX SYSTEM、REINDEX TABLE、または、REINDEX INDEXコマンドを発行します。 範囲が不明な場合は、REINDEX SYSTEMを使用して、そのデータベースの全てのシステムインデックスを再構成してください。 その後、シングルユーザ状態のサーバセッションを停止して、実サーバを再起動します。 シングルユーザ状態のサーバインタフェースの操作方法についての詳細は、postgresマニュアルページを参照してください。
その他、コマンドラインで-Pを指定して実サーバセッションを起動することもできます。 具体的な方法は、クライアントによって異なります。 しかし、libpqベースのクライアントであれば、クライアントを起動する前にPGOPTIONS環境変数を-Pに設定すれば実現できます。 この方法では他のクライアントを締め出す必要はありませんが、修復が終わるまで破損したデータベースへの他のユーザの接続を防止する方が良いことに注意してください。
共有システムカタログ(pg_authid、pg_auth_members、pg_database、pg_pltemplate、pg_shdepend、pg_shdescription、pg_tablespace)のいずれかのインデックスが破損した疑いがある場合は、スタンドアロンサーバを使用して修復しなければいけません。 REINDEXは、マルチユーザモードでは共有カタログを処理しません。
共有システムカタログ以外の全てのインデックスでは、REINDEXはクラッシュセーフかつトランザクションセーフです。 ただし、共有インデックスに対するREINDEXはクラッシュセーフではありません。 これが、通常の運用状態で実行できない理由です。 スタンドアロンモードで、これらのカタログのインデックス再作成処理中に問題が発生した場合、問題が修正されるまで実サーバを再起動することができなくなります (共有インデックスの再構築が不十分であることを示す症状として、"index is not a btree"というエラーが発生することがよくあります)。
REINDEXは、インデックスの中身を1から作り直すという点では、インデックスを削除してから再作成する処理と似ています。 しかし、ロックに関しては異なります。 REINDEXはインデックスの元となるテーブルの書き込みをロックしますが、読み込みはロックしません。 また、処理中のインデックスに対する排他ロックを取得するので、そのインデックスを使用する読み込みはブロックされます。 一方、DROP INDEXは瞬間的に元となるテーブルの排他ロックを取得するので、書き込みも読み込みもブロックされます。 その後に行うCREATE INDEXでは書き込みのみをロックし、読み込みはロックしません。 インデックスは存在しないので、インデックスを使用する読み込みは発生しません。 したがって、読み込みがブロックされることはありませんが、コストが高いシーケンシャルスキャンの使用を強制されることになります。 この他、削除してから再作成する方法では、キャッシュ済みのインデックスを使用する問い合わせ計画が無効になりますが、REINDEXでは無効にならないことも重要な違いです。
単一インデックスまたは単一テーブルのインデックス再作成を行うには、そのインデックスまたはテーブルの所有者でなければなりません。 データベースに対するインデックス再作成を行うには、データベースの所有者でなければなりません(したがって、この所有者は他のユーザが所有するテーブルのインデックスを再作成することができます)。 もちろん、スーパーユーザは常にすべてのインデックス再作成を行うことができます。
PostgreSQL 8.1より前まででは、REINDEX DATABASEは名前から想像されるすべてのインデックスに対する処理ではなく、システムインデックスのみを処理していました。 REINDEX SYSTEMで、この以前の処理を行わせることができます。
PostgreSQL 7.4より前までは、REINDEX TABLEはTOASTテーブルに対して自動的に処理を行いませんでした。 そのため、別のコマンドでインデックスを再作成しなければなりませんでした。 現在でもこれは可能ですが、冗長です。