これはPGroonga 2.X用のドキュメントです。古いPGroongaを使っているならPGroonga 1.xのドキュメントを見てください。

pgroonga_wal_truncate関数

概要

pgroonga_wal_truncate関数はPGroongaのWALをすべて削除します。PostgreSQLのWALではなくPGroongaのWALであることに注意してください。PGroongaのWALはこの関数を呼ばない限り削除されません。バックアップをとっていればPGroongaのWALを削除できます。

PGroongaのWALをすべて削除してもPGroongaのWALが使っているディスク使用量は減らないことに注意してください。使用されていたディスク領域は新しく追加するWALが再利用します。

PGroongaのWALを使う場合、PGroongaのWALのディスク使用量について検討する必要があります。なにもしないとPGroongaのWALは増え続けます。対策は次のどちらかです。

  1. 定期的にバックアップをとり、PGroongaのWALを削除する。

  2. 定期的にPGroongaのインデックスを再作成する。PGroongaのWALは次のVACUUM時に削除される。

構文

この関数の構文は次の通りです。

bigint pgroonga_wal_truncate(pgroonga_index_name)

pgroonga_index_nametext型の値です。すべてのWALを削除したいPGroongaのインデックスの名前を指定します。

削除したPostgreSQLのデータブロック数を返します。PGroongaのWALはPostgreSQLのデータブロックに記録してあります。

この関数の別の構文は次の通りです。

bigint pgroonga_wal_truncate()

すべてのPGroongaのインデックスのすべてのWALを削除します。

削除したPostgreSQLのデータブロック数を返します。PGroongaのWALはPostgreSQLのデータブロックに記録してあります。

使い方

サンプルスキーマとデータは次の通りです。

SET pgroonga.enable_wal = yes;

CREATE TABLE memos (
  content text
);

CREATE INDEX pgroonga_memos_index
          ON memos
       USING pgroonga (content);

INSERT INTO memos VALUES ('PGroonga (PostgreSQL+Groonga) is great!');

PGroongaのデータベースが壊れた状況を再現します。

SELECT pgroonga_command('delete',
                        ARRAY[
                          'table', 'IndexStatuses',
                          'key', 'pgroonga_memos_index'::regclass::oid::text
                        ])::json->>1;
--  ?column? 
-- ----------
--  true
-- (1 row)
SELECT pgroonga_command('table_remove',
                        ARRAY[
                          'name', 'Lexicon' ||
                                  'pgroonga_memos_index'::regclass::oid ||
                                  '_0'
                        ])::json->>1;
--  ?column? 
-- ----------
--  true
-- (1 row)
SELECT pgroonga_command('table_remove',
                        ARRAY[
                          'name', pgroonga_table_name('pgroonga_memos_index')
                        ])::json->>1;
--  ?column? 
-- ----------
--  true
-- (1 row)

通常、PGroongaのWALを使って自動的にPGroongaのインデックスを復旧できます。しかし、PGroongaのインデックスに対するPGroongaのWALが削除されている場合は自動で復旧できません。(明示的に再作成することで壊れたPGroongaのインデックスを復旧することはできます。)

SELECT pgroonga_wal_truncate('pgroonga_memos_index');
--  pgroonga_wal_truncate 
-- -----------------------
--                      2
-- (1 row)
SELECT * FROM memos WHERE content &@~ 'Groonga';
-- ERROR:  pgroonga: object isn't found: <Sources555045>

PGroongaのインデックスの名前は省力できます。PGroongaのインデックスの名前を省略すると、すべてのPGroongaのインデックスのすべてのWALを削除します。

SELECT pgroonga_wal_truncate();
--  pgroonga_wal_truncate 
-- -----------------------
--                      2
-- (1 row)

バックアップとPGroongaのWALの削除

PGroongaのデータはクラッシュセーフではありません。PGroongaのWALを有効にしている場合はPGroongaのデータだけバックアップをとればより速く復旧できます。PostgreSQL全体のデータをバックアップする必要はありません。バックアップにはrsyncが便利です。

ストレージ故障に対応するために別のホストにPostgreSQLのバックアップを作るべきだということは忘れないでください。

以下はバックアップを作成し、リストアするシェルスクリプトの例です。

db_name="YOUR_DB_NAME"

# Detect database information
db_oid=$(psql \
  --dbname ${db_name} \
  --no-psqlrc \
  --no-align \
  --tuples-only \
  -c "SELECT datid FROM pg_stat_database WHERE datname = '${db_name}'")
data_dir=$(psql \
  --dbname ${db_name} \
  --no-psqlrc \
  --no-align \
  --tuples-only \
  -c "SHOW data_directory")

# Define directories
db_dir=${data_dir}/base/${db_oid}
backup_dir=${data_dir}/../../backup

# Create backup directory
mkdir -p ${backup_dir}

# Stop PostgreSQL
systemctl stop postgresql-10

# Create backup
rsync -a --include '/pgrn*' --exclude '*' --delete ${db_dir}/ ${backup_dir}/

# Run PostgreSQL
systemctl start postgresql-10

# Remove PGroonga's WAL
#
# You must not change your data
# between creating backup and running pgroonga_wal_truncate
psql --dbname ${db_name} -c "SELECT pgroonga_wal_truncate()"

# ...PostgreSQL is crashed...

# Restore from backup
rsync -a --include '/pgrn*' --exclude '*' --delete ${backup_dir}/ ${db_dir}/

# Run PostgreSQL again
systemctl restart postgresql-10

参考