PostgreSQLスキルアップノート(自己啓発のための個人サイト)
WALアーカイブ実装方法
【一覧に戻る】
自己都合によりマニュアルへのリンクは9.2としています。ご了承下さい。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
■■■■ PostgreSQL スキルアップノート
■■■■
■◆■■ WALアーカイブ実装方法
■■■■
■■■■
■■■■ 2012/11/10
■■■■ 使用環境:PostgreSQL9.1.4 (CentOS6.2)
(C) 2012 ohdb
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
【マニュアル】
・サーバの設定-ログ先行書き込み(WAL)→●[マニュアル]
【マニュアル参考】
・継続的アーカイブとポイントインタイムリカバリ(PITR)→●[マニュアル]
・pg_archivecleanup→●[マニュアル]
pg_archivecleanupは9.0から。
■1■ 概要
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
・継続的アーカイブを行うには、たまったWALを自動的にアーカイブしていく設定を行う必要がある。
設定というよりもアーカイブ処理含めてユーザ側が自分で作り込む必要あり。
PostgreSQLはそのアーカイブ処理を必要に応じて呼び出し実行していく。
・WAL関連予備知識
・WALセグメントファイル・・pg_xlogディレクトリ
・WALのサイズ・・通常は1個16メガバイト。構築時に変更可。
・WALの個数・・数個
・WALアーカイブを行わない場合は、自動的にファイル名の番号を変えながら再利用されていく。
■2■ WALアーカイブ実装方法
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
いずれも postgresql.confを編集
wal_level = archive
archive_mode = on
archive_timeout = 600s (例)
archive_command = 'アーカイブコマンド'
■3■ 詳細・archive_timeoutの意味
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
archive_timeoutはトランザクションがほとんど発生しない「なぎ」のとき、WALにたまっ
た内容がいつまで経ってもアーカイブされないことを防ぐ。
デフォルトでは0(機能無効)
サイズは中身の大小にかかわらず満杯のWALと同じ大きさ。(9.2現在)
このため間隔が短かいと無駄の多いWALアーカイブが大量発生する。
マニュアル(9.2)では1分程度が妥当とある。
この場合、たとえ1つしか更新がなくても1分経過後までにはアーカイブされ、16MBが生まれる。
必ず最低1分間に16MB発生するという訳ではない(補足参照)が
トランザクションの出方(タイミング)によっては、
16MB*60回/時*24時間=23040MB/日 が発生しうる。
【補足】
どのトランザクションも最低この時間経過したらアーカイブされる、という意味であり
指定した間隔ごとに必ずアーカイブが発生するという意味ではない。
無風状態が続くのならその間アーカイブは一切発生しない。
お客さんが誰も乗らなければバスは発車しないが、もし一人でも乗れば、
「最初のお客さんからみて」timeout秒のうちには必ず発車しますというイメージ。
【実機確認・archive_timeout30秒の場合】
・insert文実行
【□】 show archive_timeout;insert into t5 values('aaa');\! date
archive_timeout
-----------------
30s
INSERT 0 1
2012年 11月 11日 日曜日 13:49:00 JST★
・WALアーカイブ実行時刻確認
[postgres@kvm00 walarc]$ ls -ltr --time-style=+'%Y/%m/%d %H:%M:%S'|tail -5;date
:
-rw------- 1 postgres postgres 16777216 2012/11/11 13:49:28★ 00000001000000000000009B
:
以上、設定より若干早め(28秒後)にWALがアーカイブされた。
■4■ 詳細・archive_command
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
archive_command = 'cp %p アーカイブ先ディレクトリ/%f' (もっとも簡単な例)
%p:アーカイブ対象のパス名に置換される ・・・pg_xlog/000000010000000000000019のように置換
%f:ファイル名に置換される ・・・000000010000000000000019 のように置換
・%pのパス名は、$PGDATAから見た相対パス
・cp先のファイル名は64文字以下となるようにすること。 ASCII文字,数字,ドット
1.直にcpコマンドを設定する例(archive_command)
──────────────────────────────
・いずれの場合も、最低限エラー時(0以外終了時)にpostgresのログには記録される。
archive_command = 'cp %p /walarc/%f'
・・・単純にコピーだけ。
archive_command = 'test ! -f /walarc/%f && cp %p /walarc/%f'
・・・アーカイブ先の同名ファイルをチェックしてからcp(マニュアル記載例と同程度)
archive_command = 'test ! -f walarc/%f && (echo "`date "+%Y/%m/%d %T"` %p archive";cp %p walarc/%f) 1>&2'
・・・正常も異常もすべて標準エラー出力に出させる(1>&2)ことでpostgreSQLのログコレクターに拾わせる。
pg_log/postgresql-2012-11-10_224215.log
--------------------------------------------------------------------------------------
2012-11-10 22:40:48 JST [postgres](12991)LOG: statement: insert into t6 values('a');
2012-11-10 22:40:48 JST [postgres](12991)LOG: duration: 11.498 ms
2012/11/10 22:40:49 pg_xlog/00000001000000000000007C
:
2012/11/10 22:43:04 pg_xlog/00000001000000000000007F archive
cp: cannot create regular file `walarc/00000001000000000000007F': No such file or directory
2012-11-10 22:43:04 JST [](13022)LOG: archive command failed with exit code 1
2012-11-10 22:43:04 JST [](13022)DETAIL: The failed archive command was: test ! -f walarc/00000001000000000000007F && (echo "`date "+%Y/%m/%d %T"` pg_xlog/00000001000000000000007F archived";cp pg_xlog/00000001000000000000007F walarc/00000001000000000000007F) 1>&2
--------------------------------------------------------------------------------------
archive_command = 'test ! -f walarc/%f && (date;echo %p;cp %p walarc/%f)>>walarc_`date "+%Y%m%d"`.log 2>&1'
・・・専用のログファイルを作り、正常時もエラー時も日時やファイル名とともに記録。
ただし、cpをコマンドを一番最後に持ってこないとcpのエラーは拾えない。
一行の範囲内でもっと作りこめば可能だが・・
$PGDATA/walarc_YYYYMMDD.log
-----------------------------------------------------------------------------------
2012/11/10 22:11:25 pg_xlog/00000001000000000000006A
2012/11/10 22:11:26 pg_xlog/00000001000000000000006B
2012/11/10 22:12:07 pg_xlog/00000001000000000000006C
cp: cannot create regular file `walarc/00000001000000000000006C': No such file or directory
2012/11/10 22:12:08 pg_xlog/00000001000000000000006C
cp: cannot create regular file `walarc/00000001000000000000006C': No such file or directory
2012/11/10 22:13:08 pg_xlog/00000001000000000000006C
2012/11/10 22:13:08 pg_xlog/00000001000000000000006D
-----------------------------------------------------------------------------------
2.スクリプトを作成して設定する例
──────────────────────────────
PostgreSQLマニュアルでは「archive_commandスクリプト」の項で事実上スクリプト化を推奨している。
本番運用に耐えられるきちんとした処理を組み込もうと思えば、やはりシェルスクリプト化が必須と思う。
archive_command = 'user_script/walarc.sh %p %f'
┌────────────────────────┐
│ スクリプト例は未整備 │
└────────────────────────┘
・実行はPostgreSQLサーバ起動したユーザと同じ所有権で行われる。
・終了ステータスは必ず成功を0、失敗は0以外とすること。
・0を受けてpostgreSQL側でファイルの削除・回収が行われる。
・0が戻らなければ、成功するまで定期的に再試行。
・他のユーザからは参照できないディレクトリにすること。
■5■ その他メモ
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. pg_archivecleanup
──────────────────────────────
pg_archivecleanup ・・walアーカイブを消去 9.0から登場
http://www.postgresql.jp/document/9.2/html/pgarchivecleanup.html
例 archive_cleanup_command = 'pg_archivecleanup -d walrc %r 2>>cleanup.log'
なお、コマンド単体で、
pg_archivecleanup /home/postgres/data/walarc 00000001000000000000002A
とするとwalarcディレクトリの中の00000001000000000000002A
より前はすべて削除される。
2.pg_switch_xlog
──────────────────────────────
手作業でセグメント切り替えを強制。
select pg_switch_xlog();
pg_start_backup(label text [, fast boolean ])
select pg_start_backup('label1') ;
select pg_stop_backup();
この他のWAL管理に関連した関数 表9-59参照
以上