REINDEX

名前

REINDEX -- インデックスを再構築する

概要

REINDEX { INDEX | TABLE | DATABASE | SYSTEM } name [ FORCE ]

説明

REINDEXは、インデックスのテーブルに保存されたデータを使用してインデックスを再構築し、古いインデックスのコピーと置き換えます。 以下にREINDEXが使用される状況を示します。

パラメータ

INDEX

指定したインデックスを再作成します。

TABLE

指定したテーブルの全インデックスを再作成します。 テーブルに2次的な"TOAST"テーブルがあっても、同様にインデックスを再作成します。

DATABASE

現在のデータベースのすべてのシステムインデックスを再作成します。 また、スタンドアロンモード(後述)以外のモードでは、共有システムカタログのインデックスは処理されません。 この構文のREINDEXをトランザクションブロック内で実行することはできません。

SYSTEM

現在のデータベースのすべてのシステムカタログのインデックスを再作成します。 ユーザテーブルのインデックスは処理されません。 また、スタンドアロンモード(後述)以外のモードでは、共有システムカタログのインデックスは処理されません。 この構文のREINDEXをトランザクションブロック内で実行することはできません。

name

インデックスを再作成するインデックス、テーブル、データベースの名前です。 インデックスとテーブルはスキーマで修飾可能です。 現状では、REINDEX DATABASEREINDEX SYSTEMは現在のデータベースのインデックスのみを再作成することができます。 そのため、このパラメータは現在のデータベース名と一致する必要があります。

FORCE

このオプションは廃止されました。 指定されても無視されます。

注釈

ユーザテーブル上の特定のインデックスに破損の疑いがある場合、そのインデックスを再構築してください。 テーブル上の全てのインデックスに破損の疑いがある場合は、REINDEX INDEXREINDEX TABLEを使用してください。

システムテーブルのインデックスの破損を復旧する場合の手順はより複雑になります。 この場合、システムによって破損の可能性があるインデックス自体が使用されないようにすることが重要です (実際は、このようなケースでは、破損したインデックスに依存していたため、サーバプロセスが起動時に強制終了してしまう可能性があります)。 安全に復旧させるには、システムカタログ検索時のインデックスの使用を禁止する-Pオプションを使用してサーバを起動しなければなりません。

考えられる方法の1つは次の方法です。まず、サーバを停止して、コマンドラインから-Pオプションを指定してシングルユーザ状態のPostgreSQLサーバを起動します。 そして、再構成する範囲に応じて、REINDEX DATABASEREINDEX SYSTEMREINDEX TABLE、または、REINDEX INDEXコマンドを発行します。 範囲が不明な場合は、REINDEX SYSTEMを使用して、そのデータベースの全てのシステムインデックスを再構成してください。 その後、シングルユーザ状態のサーバセッションを停止して、実サーバを再起動します。 シングルユーザ状態のサーバインタフェースの操作方法についての詳細は、postgresマニュアルページを参照してください。

その他、コマンドラインで-Pを指定して実サーバセッションを起動することもできます。 具体的な方法は、クライアントによって異なります。 しかし、libpqベースのクライアントであれば、クライアントを起動する前にPGOPTIONS環境変数を-Pに設定すれば実現できます。 この方法では他のクライアントを締め出す必要はありませんが、修復が終わるまで破損したデータベースへの他のユーザの接続を防止する方が良いことに注意してください。

共有システムカタログ(pg_authidpg_auth_memberspg_databasepg_pltemplatepg_shdependpg_shdescriptionpg_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テーブルに対して自動的に処理を行いませんでした。 そのため、別のコマンドでインデックスを再作成しなければなりませんでした。 現在でもこれは可能ですが、冗長です。

単一のインデックスを再構築します。

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はありません。