詳解 PostgreSQL[10/11対応]―現場で役立つ新機能と実践知識

第4章 PostgreSQL の運用に便利な機能―バックアップ,レプリケーション,パーティション,バージョンアップ

この記事を読むのに必要な時間:およそ 8 分

バックアップとリストア─⁠─転ばぬ先の杖

最終章は運用についてです。

運用でまず重要なのは,バックアップとリストアです。データの死はサービスの死と言っても過言ではありません。PostgreSQLのバックアップとリストアを学んでいきましょう。本節では,はじめにRDBMSのバックアップの種類とリストアの設計をおさらいします。そのあと,PostgreSQLでのバックアップツールや勘どころを紹介します。自分のバックアップのやり方を見なおす機会にご活用ください。

そのあとの節では,運用で役立つレプリケーション,パーティション,バージョンアップ,日本語ドキュメントについて解説します。各節を通して,PostgreSQLを実際に使っていくうえでの勘どころを押さえましょう。

バックアップの種類

バックアップには次の種類があります。

論理バックアップ
SQLをそのまま保存する。無停止かつお手軽に実施できる。バックアップした時点までしか戻せない
物理バックアップ
サーバを止めてデータファイルをコピーする。多くの場合,論理バックアップより高速に実施できる。バックアップした時点までしか戻せない
オンラインバックアップとPITRPoint In Time Recovery
無停止でデータファイルとWALアーカイブをコピーする。最新状態までの任意の時点に戻せる。運用コストは高くなる

論理バックアップは一般的に,無停止でお手軽な反面,データサイズが大きくなるとバックアップの時間が延び,リストア時間もそれに合わせて長くなります。それに対して物理バックアップは,停止を伴いますが,rsyncなどでファイルバックアップすればよく,高速に実行できます。どちらも運用はシンプルですが,リストアはバックアップした時点までしか戻せません。

バックアップした直後から最新状態までの任意の時点に戻すには,バックアップ後からの差分が必要になります。この差分を埋めるために,WALを利用したバックアップと,リストアの手法としてPITRを利用する必要があります。PITRは万能に見えますが,データファイルとWALアーカイブの両方の管理が必要なため運用コストが高くなり,リストアにはエンジニアのスキルが必要になります。

このようにそれぞれ,メリットとデメリットがあります。

リストアの設計

リストアを設計するうえでのポイントは稼働率です。表1のように,稼働率から年間の停止可能時間が決まるわけですから,それによって障害対応する場合のバックアップとリストアの方針も決まります。

表1 稼働率

稼働率年間停止時間バックアップとリストアの方針
90%36.5日間月に複数回のメンテナンス時間を設けることができる。論理バックアップや物理バックアップとリストアで十分に対応できる
99%3.65日間オンプレミスなら予備のマシンが必要になる。大規模なデータの場合はリストアの所要時間の把握などが必要になる
99.9%8.7時間法定停電や24時間365日対応などシステム以外の部分にも影響が出る99.99% 52分間バックアップからのリストアだけでは達成が難しいため,コールドスタンバイなど冗長化のしくみが必要になる
99.999%5分間レプリケーションを利用した,すぐに切り替えられる予備サーバ(ホットスタンバイ)やDRDisaster Recoveryなどの専用のしくみが必要になる
99.9999%32秒間無停止で運用する専用サーバや,大規模な冗長構成のシステムやハードウェアが必要になり,急激にコストが高くなる

稼働率を高くするにはオンラインで行えるバックアップは必須ですし,夜間などで定期的に停止できるのであれば物理バックアップは高速でお手軽です。どちらも優越ではなく,バックアップの種類と稼働率を踏まえながら,自分たちに合った計画を組むことが重要です。

自分たちの稼働率を決めて,運用方針を決めれば,次は具体的なバックアップとリストアの手法です。以降では,PostgreSQLのバックアップ手法を見ていきましょう。

pg_dump─⁠─オンラインで論理バックアップ

一番スタンダートなのは論理バックアップツールであるpg_dumpです。pg_dumpはPostgreSQLに同梱されており,次の4種類からバックアップファイルの形式を選べます。

  • プレーンテキスト形式(SQL)
  • カスタムアーカイブ形式(圧縮したバイナリ)
  • ディレクトリ形式(表単位で圧縮したバイナリ)
  • TAR形式(表単位のバイナリ)

お勧めは,カスタムアーカイブ形式です。カスタムアーカイブ形式は,サイズを圧縮できるうえに,リストアの際に必要なテーブルやスキーマ定義だけを分離できます。必要であればプレーンテキスト形式にも変換できるため,いざという場合はSQL文を手作業で編集できます。

カスタムアーカイブ形式でのバックアップとリストアは次のように実行します。

カスタムアーカイブ形式でのバックアップ

$ pg_dump -Fc データベース名 -U ユーザー名 \
 -h ホスト名 -f /tmp/dump.custom

リストア

$ pg_restore -d データベース名 /tmp/dump.custom

このようにDBの停止を伴わずコマンド一つでバックアップし,復旧方法もコマンド一つですから,運用はシンプルになります。

pg_basebackup─⁠─PITRのためのオンラインバックアップ

pg_basebackupは,pg_dumpと同様にPostgreSQLに同梱されており,PITRでリストアするためのデータファイルをオンラインでバックアップするツールです。PostgreSQL 9.1から提供されました。

pg_basebackupはDBを停止しないため,バックアップ中も更新が発生します。そこで,バックアップ中に発生したWALの更新履歴を取得するために,postgresql.confを次のように変更してWALアーカイブモードを有効にしておく必要があります。

wal_level = replica
archive_mode = on
archive_command = 'test ! -f /usr/local/pgsql/backup/%f
&& cp %p /usr/local/pgsql/backup/%f'

wal_levelのデフォルトはreplicaになっており,9.6までのデフォルトのminimalの場合はarchive_modeの設定は無視されます。wal_levelにreplicaが設定されたうえで,archive_modeをonにした場合,アーカイブしたWALを保存するコマンドをarchive_commandに指定する必要があります。上記の例では同じサーバに保存していますが,rsyncなどで別のサーバに保存することもできます。

pg_basebackupで作成したバックアップファイルとアーカイブされたWALの合わせ技で,オンラインで完全にデータをバックアップでき,リストアの際も完全に復旧できるのです。

具体的なバックアップとリストアの方法は,次の手順になります。なお,バックアップはオンラインで行えますが,リストアの際はDBへの接続をなくすためにDBを停止してから行いましょう。

PostgreSQLの停止

# service postgresql stop

バックアップ

$ pg_basebackup -D 出力先 -X s -P \
 -h ホスト名 -U ユーザー名

アーカイブ

$ pg_basebackup -D 出力先 -X s -P \
 -h ホスト名 -U ユーザー名

ここからリストア手順。まず最新のWALを避難

$ rsync -av $PGDATA/pg_wal/ $BACKUP_WAL

既存のデータを避難し,削除

$ rsync -av $PGDATA $BACKUP/old_pgdata
$ rm -rf $PGDATA

pg_basebackupで取得したバックアップを配置

$ rsync -av $BACKUP/pgdata/* $PGDATA

古いWALを削除し,避難した最新のWALを配置

rm -rf $PGDATA/pg_wal
$ rsync -av $BACKUP_WAL $PGDATA/pg_wal/

WALアーカイブの場所と復元ポイントの設定

$ vi recovery.conf
restore_command = 'cp /usr/local/pgsql/backup/%f "%p"'
recovery_target_time = '2018/12/01 00:47:00'

PostgreSQLの起動

# service postgresql start

リストア時には,pg_basebackupで取得したバックアップからデータファイルを展開します。そのあと,避難した最新のWALを配置してPostgreSQLを起動すると,WALからバックアップとの差分を取得し,DBを復旧してくれます。

recovery.confで指定しているrestore_commandは,前述のarchive_commandで保存したWALアーカイブの保存先から取得するコマンドです。recovery_target_timeには,リカバリで戻したい日時を指定します。recovery_target_timeを指定しなかった場合,WALアーカイブとWALファイルから復元できるところまで復元します。

このようにpg_basebackupと稼働中の差分のWALさえあれば,障害直前まで戻すことができます。これが,PostgreSQLのPITRのしくみです。

pg_rman─⁠─PITRを助けてくれるツール

「PITRをしたいけどリストア手順が多くて難しい……」という人にお勧めのツールがpg_rmanです。PostgreSQL 11にも対応しており,ソースコードも公開されています。

pg_rmanはpg_basebackupを使ったバックアップとPITRのリストアを簡略化して実施するためのツールです。pg_rmanを利用して作成したバックアップであれば,次のように簡単に最新の状態に復旧できます。もちろん,PITRのメリットである任意の時間にも対応しています。

バックアップ

# pg_rman backup --backup-mode=full \
  --compress-data --progress

PostgreSQLの停止

# service postgresql stop

リストア

# pg_rman restore \
--recovery-target-time "2018/12/01 00:47:00"

PostgreSQLの起動

# service postgresql start

バックアップをより詳しく知りたい方へ

チュートリアルの動画PGCon 2014 Tokyo【D1】PostgreSQL バックアップ入門(佐藤 千佳⁠⁠」が公開されています。当日の登壇資料も公開されています。

著者プロフィール

曽根壮大(そねたけとも)

株式会社オミカレ副社長兼CTO。数々の業務システム,Webサービスなどの開発・運用を担当し,2017年に株式会社はてなでサービス監視サービス「Mackerel」のCRE(Customer Reliability Engineer)を経て現職。 コミュニティでは,Microsoft MVPをはじめ,日本PostgreSQLユーザ会の理事として勉強会の開催を担当し,各地で登壇している。 builderscon 2017,YAPC::Kansaiなどのイベントでベストスピーカーを受賞し,分かりやすく実践的な内容のトークに定評がある。 他に,岡山Python勉強会を主催し,オープンラボ備後にも所属。著書に『Software Design』誌で,データベースに関する連載「RDBアンチパターン」をまとめた『失敗から学ぶRDBの正しい歩き方』を執筆。

@soudai1025
はてなid:Soudai

著書