Ludia / REINDEXをバッチで実行する
【追記】
Ludia 0.9ではREINDEXが可能となっているので、既にLudia0.9以前のバージョンを導入している方向けの情報になります。
see also, id:solitary_shell:20061213:1166031150
【/追記】
id:solitary_shell:20061101:1162441618で書いたように現時点のLudiaのバージョン(ludia-0.8.0)ではREINDEXができないので、PerlとSQL文にてREINDEXを実行するスクリプトを作成してみました。参考にした情報は、ludia-0.8.0内に含まれるREADMEファイルです。
インデックスの削除
- -
PostgreSQLのインデックスリレーションファイルは、
Ludiaのインデックスファイルは以下の5つから構成されます。
(テーブル空間を使用している場合は、テーブル空間定義時に指定した場所に置かれます。)
- PGDATA/base/データベースのOID/インデックスのファイルノード番号
- PGDATA/base/データベースのOID/インデックスのファイルノード番号.SEN
- PGDATA/base/データベースのOID/インデックスのファイルノード番号.SEN.i
- PGDATA/base/データベースのOID/インデックスのファイルノード番号.SEN.i.c
- PGDATA/base/データベースのOID/インデックスのファイルノード番号.SEN.l
1 はPostgreSQLのインデックスリレーションファイル、
2〜5はSennaのインデックスファイルです。
2〜5のファイルは手作業で削除する必要があります。参考として、インデックスのファイルノード番号は以下のようなクエリで取得できます。::
SELECT relfilenode FROM pg_class WHERE relname = 'index1';また、データベースのOIDは以下のようなクエリで取得できます。::
SELECT oid FROM pg_database WHERE datname = 'dbname';1のファイルについては、DROP INDEXを実行することで削除されます。::
DROP INDEX index1;
ちなみにデータベース名とテーブルスペース名は以下のように作成してあります。
データベース名: sample テーブルスペース名: sample (/db/pgsql/data/sample)
実際のSQL文は以下になります。
SELECT 'DROP INDEX ' || i.indexname || ';' AS DROP_SQL, i.indexdef || ';' AS CREATE_SQL, tmp.tbs_base || c.relfilenode || '.SEN' AS RM_INDEX_1, tmp.tbs_base || c.relfilenode || '.SEN.i' AS RM_INDEX_2, tmp.tbs_base || c.relfilenode || '.SEN.i.c' AS RM_INDEX_3, tmp.tbs_base || c.relfilenode || '.SEN.l' AS RM_INDEX_4 FROM pg_class c INNER JOIN pg_indexes i ON c.relname = i.indexname, ( SELECT t.spclocation || '/' || d.oid || '/' AS tbs_base FROM pg_database d, pg_tablespace t WHERE d.datname = 'sample' AND t.spcname = 'sample' ) tmp WHERE c.relname = 'idx_m_address_senna';
ざっと説明すると、DROP INDEX文、CREATE INDEX文、Sennaのインデックスファイルの削除用のコマンドになります。(Linuxしか想定していません)
実際のSQLの実行結果は以下の通りになります。
sample=> SELECT 'DROP INDEX ' || i.indexname || ';' AS DROP_SQL, sample-> i.indexdef || ';' AS CREATE_SQL, sample-> tmp.tbs_base || c.relfilenode || '.SEN' AS RM_INDEX_1, sample-> tmp.tbs_base || c.relfilenode || '.SEN.i' AS RM_INDEX_2, sample-> tmp.tbs_base || c.relfilenode || '.SEN.i.c' AS RM_INDEX_3, sample-> tmp.tbs_base || c.relfilenode || '.SEN.l' AS RM_INDEX_4 sample-> FROM sample-> pg_class c sample-> INNER JOIN pg_indexes i ON c.relname = i.indexname, sample-> ( sample(> SELECT t.spclocation || '/' || d.oid || '/' AS tbs_base sample(> FROM pg_database d, sample(> pg_tablespace t sample(> WHERE d.datname = 'sample' sample(> AND t.spcname = 'sample' sample(> ) tmp sample-> WHERE c.relname = 'idx_m_address_senna'; drop_sql | create_sql | rm_index_1 | rm_index_2 | rm_index_3 | rm_index_4 ---------------------------------+----------------------------------------------------------------------+---------------------------------------+-----------------------------------------+-------------------------------------------+----------------------------------------- DROP INDEX idx_m_address_senna; | CREATE INDEX idx_m_address_senna ON m_address USING fulltext (city); | /db/pgsql/data/sample/16391/61455.SEN | /db/pgsql/data/sample/16391/61455.SEN.i | /db/pgsql/data/sample/16391/61455.SEN.i.c | /db/pgsql/data/sample/16391/61455.SEN.l (1 row)
その結果を元にPerlスクリプトで以下のロジックを実装することになります。
- インデックスの削除
- Sennaインデックスファイルの削除
- インデックスの作成
動作確認をして問題がないことを確認した上で、cronに仕込んで自動的にREINDEXを行なうようにします。
see also,