アクセラと+αな生活
アクセラとα350と共に過ごす気まぐれ日記です。
Firefox ブラウザ無料ダウンロード
2017年09月
≪08月  1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30    10月≫
スポンサーサイト
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
PostgreSQL のオンラインバックアップですが、非常に苦労しています。。。><;

WAL をデータベースと別ディスクに保存するようにしました。
これで、データベース領域のディスクが障害でダウンしても障害発生時点まではデータを戻すことができるようになりました。
しかし、WAL が保存されているディスクがダウンした場合には、障害発生の直前まで、データが戻せないようです。。。


う~ん、いろいろなところで、PostgreSQL 8は高評価を受けているようですが、実際に可用性を考慮したシステムを構築するとなると、まだまだ成熟の域には達していないと言えますね。。。

とはいえ、戻せないから何もしない。。。という訳にはいきません。

PostgreSQL 8.0.3のドキュメント(http://www.postgresql.jp/document/pg803doc/html/backup-online.html)からの抜粋ですが、最新の WAL を独自で別領域にコピーしておく必要があります。。。とほほ。
<PostgreSQL 8.0.3のドキュメントの抜粋>
現在の状態まで正しく復旧できることを目的とするのであれば、現在のまだ完了していないWALセグメントも確実にどこかにコピーできるように追加処理を行う必要があります。 WALセグメントが完了し保管できるようになるまでに長時間かかることになりますので、生成されるWAL流量が小さな(、もしくはWALへの書出し速度が低速な)サーバでは特に重要です。これを扱う方法の1つは、定期的(毎分間隔かもしれません)に現在のWALセグメントファイルを識別してどこかに安全に保存するジョブをcronで設定することです。保管済みWALセグメントとこの保存した現在のセグメントを組み合わせることで、確実に現時点から1分以内の状態まで復旧できるようになります。現在、この振舞いはまだPostgreSQLに組み込まれていません。これは、内容が異なる同じWALファイルを連続的に保管することを仕様とすることによって、archive_commandの定義が複雑になることを避けたいためです。 archive_commandは、WALセグメントが完了した時にのみ呼び出されます。また、失敗のための再試行の場合は例外ですが、指定されたファイル名に対しては1度のみ呼び出されます。


WAL の書き出し(archive_command)に関しては、現在の WAL に対してタイムラグなしで実行されると勘違いしておりました。。。><;
知識不足でした。

Postgre 8の仕様なので仕方ないですが、定期間隔で現在の WAL を含めたバックアップを取得することで、リカバリポイントを障害発生時間に少しでも近づけるしかないようです。
幸いオンラインバックアップも可能ですし、rsync コマンドを使用すれば、差分をコピーするので、処理時間も短くなりますので、何とかいけそうな感じww

でなわけで、オンラインバックアップのシェルを作成してみました。
このシェルを10分など、一定間隔で実行するようにして対応することにします。

#! /bin/sh
#######################################
#
# PostgreSQL オンラインバックアップ
#
#######################################

backup_log_dir=/var/log/
backup_log_name=backup.log
backup_log_file=$backup_log_dir$backup_log_name
backup_area=/mnt/backup
backup_device=/dev/hdd1

pgdata_dir=/var/lib/pgsql/data
pgwal_dir=/var/archives/pg_xlog
pgarchive_dir=/var/archives/pg_xlog_back

# アーカイブログの保存期間(日)
delete_limit=3

func_echo ()
{
echo '['`date +'%Y/%m/%d %T %Z'`']' `hostname` $1 >> $2
}

func_job_stop ()
{
func_echo '※バックアップジョブを中止しました' $1
exit $2
}

# バックアップ(rsync)
func_rsync_backup ()
{
rsync -a --delete $1 $2
rc=$?

if [ "$rc" == "0" ];then
func_echo $1'のバックアップが完了しました(Return Code:'$rc')' $3
else
func_echo $1'のバックアップに失敗しました(Return Code:'$rc')' $3
fi

}


# ログ出力開始
func_echo '【PostgreSQL オンラインバックアップ】を開始します' $backup_log_file

# バックアップ領域のマウント
mount $backup_device $backup_area
rc=$?
if [ "$rc" == "0" ];then
func_echo 'バックアップ領域をマウントしました(Return Code:'$rc')' $backup_log_file
else
func_echo 'バックアップ領域のマウントに失敗しました(Return Code:'$rc')' $backup_log_file
func_job_stop $backup_log_file $rc
fi

# PostgreSQLのオンラインバックアップ準備
func_echo 'PostgreSQLのオンラインバックアップ準備を開始します' $backup_log_file
su postgres -c 'psql -q -f /usr/local/prod/sql/pg_start_backup.sql postgres' >> $backup_log_file
rc=$?
if [ "$rc" == "0" ];then
func_echo 'PostgreSQLのオンラインバックアップ準備完了しました(Return Code:'$rc')' $backup_log_file
else
func_echo 'PostgreSQLのオンラインバックアップ準備に失敗しました(Return Code:'$rc')' $backup_log_file
func_job_stop $backup_log_file $rc
fi

# データ領域バックアップ
func_echo 'データ領域のバックアップ' $backup_log_file
func_rsync_backup $pgdata_dir $backup_area/pg_data $backup_log_file

# 最新のWALバックアップ
func_echo '最新のWALのバックアップ' $backup_log_file
# 1世代前のデータは保存しておく
func_rsync_backup $backup_area/pg_data/pg_xlog $backup_area/pg_data/pg_xlog_old $backup_log_file
func_rsync_backup $pgwal_dir $backup_area/pg_data $backup_log_file

# アーカイブ領域(バックアップ)バックアップ
func_echo 'アーカイブ領域のバックアップ' $backup_log_file
func_rsync_backup $pgarchive_dir $backup_area/pg_data $backup_log_file


# PostgreSQLのオンラインバックアップ停止
func_echo 'PostgreSQLのオンラインバックアップ停止を開始します' $backup_log_file
su postgres -c 'psql -q -f /usr/local/prod/sql/pg_stop_backup.sql postgres' >> $backup_log_file
rc=$?
if [ "$rc" == "0" ];then
func_echo 'PostgreSQLのオンラインバックアップ停止完了しました(Return Code:'$rc')' $backup_log_file
else
func_echo 'PostgreSQLのオンラインバックアップ停止に失敗しました(Return Code:'$rc')' $backup_log_file
func_job_stop $backup_log_file $rc
fi

# バックアップ領域のアンマウント
umount $backup_area
rc=$?
if [ "$rc" == "0" ];then
func_echo 'バックアップ領域をアンマウントしました(Return Code:'$rc')' $backup_log_file
else
func_echo 'バックアップ領域のアンマウントに失敗しました(Return Code:'$rc')' $backup_log_file
func_echo '※処理は続行しますが、バックアップジョブ処理完了後、バックアップ領域をアンマウントして下さい' $backup_log_file
fi

# 不要なアーカイブログの削除
find $pgarchive_dir -mtime $delete_limit -exec rm {} \;
func_echo 'アーカイブログ削除処理が完了しました' $backup_log_file

# ログ出力(完了)
func_echo '【PostgreSQL オンラインバックアップ】が完了しました' $backup_log_file

exit 0

pg_start_backup.sql
select pg_start_backup('online_backup');
\q

pg_stop_backup.sql
select pg_stop_backup();
\q

このシェル、簡単にいえば、オンラインバックアップ準備、オンラインバックアップ完了のコマンドを発行しながら、データ領域(/var/lib/pgsql/data)、現行の WAL(/var/archives/pg_xlog:)、archive_command でコピーした WAL(var/archives/pg_xlog_back)をバックアップするだけです。
あ、ディレクトリはうちの環境のものなので、このシェルを流用するのでしたら、読み替えが必要です。

一応、このシェルでバックアップも採取できましたし、バックアップからのリカバリも問題なくできましたので、OKかなww

コメント
この記事へのコメント
URL :
コメント :
パスワード :
管理者にだけ表示を許可する
 
トラックバック
この記事のトラックバックURL
Template designed by アクセラと+αな生活

Powered by .
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。