PostgreSQLの「もしも」に備える!pg_dumpとpg_restoreで始めるバックアップ&リストア入門
やっほー!みんな、元気? Postgresのデータベース、日々コツコツ運用してるかな。今日はね、データベースエンジニアなら避けては通れない、でも意外と「後回しにしがち」な、バックアップとリストアについて、現場の先輩エンジニア目線で、ざっくばらんに話していこうと思うんだ。
特に、PostgreSQLでよく使われる論理バックアップ、つまり`pg_dump`と`pg_restore`を使った基本的なやり方を中心に、なんでこれが大事なのか、どうやって使うのか、具体的な例を交えながら解説していくよ。
なんでバックアップがそんなに大事なの?〜「まさか」は本当に起こる〜
いきなりだけど、みんなのデータベース、ちゃんとバックアップ取ってる? 「うちのシステムは堅牢だから大丈夫!」とか「本番環境で何かあったらその時考えればいいや」なんて思ってたりしない?
正直、僕も昔はそんな甘い考えを持ってた時期があったんだ(笑)。でもね、現場で色々なトラブルに遭遇するうちに、「まさか」は本当に起こるってことを痛感したんだよね。
- ハードウェアの突然の故障: ディスクがぶっ飛んだり、サーバーそのものが動かなくなったり…これはもう、技術の進歩をもってしても完全に防げるものではない。
- オペレーションミス: 「あ、間違えてDELETEしちゃった!」とか、「ALTER TABLEでテーブル壊しちゃった!」なんて、誰にでも起こりうること。人間だもの、ミスはある。
- ソフトウェアのバグ: まれだけど、PostgreSQL自体や、アプリケーションのバグが原因でデータが破損することだってある。
- サイバー攻撃: ランサムウェアとか、悪意のある攻撃でデータが暗号化されたり、消されたり…これはもう、他人事じゃない。
こういう時、バックアップがないとどうなるか? pretty badな状況になるのは想像に難くないよね。最悪の場合、サービス停止、顧客からの信頼失墜、そして原因究明と復旧に膨大な時間とコストがかかる。
だからこそ、「もしも」に備える、つまりバックアップは、データベース運用における「保険」なんだ。そして、その保険をちゃんと使えるように、リストアの訓練もセットでやっておくのが、プロの仕事ってもんだ。
PostgreSQLのバックアップ方法、色々あるけど…
PostgreSQLのバックアップには、大きく分けて「物理バックアップ」と「論理バックアップ」の2種類があるんだ。
- 物理バックアップ: データディレクトリの中身をそのままコピーする方法。高速だけど、バージョン間の互換性や、特定のオブジェクトだけを復旧するのが難しい場合がある。WAL(Write-Ahead Logging)を使ったPoint-in-Time Recovery(PITR)なんかがこれに当たる。
- 論理バックアップ: データベースの中身をSQL文の形式でダンプする方法。ファイルサイズは大きくなりがちだけど、人間が読める形式だし、特定のデータベースやテーブルだけをリストアしたり、異なるバージョンや異なるRDBMSへの移行にも柔軟に対応できるのが強み。
今日は、この論理バックアップに焦点を当てるよ。なぜなら、手軽に始められて、色々な状況で役立つからね。
`pg_dump` って何者?〜データベースを「まるごと」コピーする魔法〜
`pg_dump`は、PostgreSQLのデータベースを論理バックアップするためのコマンドラインツールだよ。データベースの中身をSQL文の形式でファイルに出力してくれる。
使い方はとってもシンプル。基本形はこんな感じ。
pg_dump [オプション] データベース名 > 出力ファイル名
例えば、`mydatabase`っていうデータベースを、`mydatabase_backup.sql`っていうファイルにバックアップしたいなら、こう書く。
pg_dump mydatabase > mydatabase_backup.sql
これだけで、`mydatabase`のテーブル定義、データ、インデックス、関数、ビュー…全部SQL文として`mydatabase_backup.sql`に書き出されるんだ。すごいよね!
より実践的な `pg_dump` の使い方
ただ、実際の現場では、もうちょっと色々なオプションを使いたくなることが多いんだ。いくつか紹介しよう。
- 特定のホスト、ポート、ユーザーを指定する:
ローカルで動いてるPostgresじゃない場合や、デフォルト以外のポートを使ってる場合は、これが必要になる。
pg_dump -h localhost -p 5432 -U postgres mydatabase > mydatabase_backup.sql
- 圧縮してバックアップする:
論理バックアップはファイルサイズが大きくなりがちだから、圧縮するのは必須! `-Fc` (custom format) オプションを使うと、圧縮されたバイナリ形式で出力してくれる。こっちの方が、後で`pg_restore`でリストアする時に便利なんだ。
pg_dump -Fc -h localhost -p 5432 -U postgres mydatabase > mydatabase_backup.dump
ファイル拡張子を `.dump` にしてみたけど、これは慣習みたいなもの。中身はバイナリだよ。
- 特定のテーブルだけバックアップする:
「あ、あのテーブルだけ壊れた!」なんて時に役立つのが `-t` オプション。
pg_dump -Fc -t users -t orders mydatabase > users_orders_backup.dump
これで`users`テーブルと`orders`テーブルだけをバックアップできる。
- 特定のスキーマだけバックアップする:
スキーマ単位でバックアップしたい時もあるよね。`-n` オプションを使う。
pg_dump -Fc -n public -n analytics mydatabase > public_analytics_backup.dump
- データだけ、またはスキーマ定義だけバックアップする:
「テーブル構造はもうできてるから、データだけ欲しい!」とか、「データは後で入れるから、構造だけ先に欲しい」なんて時もある。
- データのみ: `-a` (or `–data-only`)
pg_dump -a mydatabase > mydatabase_data.sql
- スキーマ定義のみ: `-s` (or `–schema-only`)
pg_dump -s mydatabase > mydatabase_schema.sql
ポイント: `-Fc` (custom format) でバックアップした場合は、これらのオプションは使えないから注意ね! `.sql` 形式で出力する場合に使うオプションだよ。
バックアップの実行頻度と保管場所
で、どれくらいの頻度でバックアップを取ればいいの? って話だけど、これはもう、「どれくらいのデータ消失なら許容できるか」で決まる。
- 毎日更新されるような重要なシステム: 毎日、できれば数時間おきに取るのが理想。
- 更新頻度が低いシステム: 週に一度とかでも良いかもしれない。
でも、大事なのは「取ったバックアップがちゃんと復旧できるか」だから、闇雲に頻度を上げても意味がない。定期的にリストアテストをするのが超重要!
保管場所も、バックアップ元とは別の場所に置くのが鉄則。さらに言えば、オフサイト(物理的に離れた場所)に保管するのがベスト。クラウドストレージとか、別のデータセンターとかね。
`pg_restore` 〜バックアップを「戻す」魔法〜
`pg_dump`で取ったバックアップを元に戻すのが`pg_restore`だよ。これもまた便利なツールなんだ。
`pg_dump`で標準SQL形式(`.sql`ファイル)でバックアップした場合、`psql`コマンドでリストアできる。
psql -h ホスト -p ポート -U ユーザー -d データベース名 < バックアップファイル名 例: psql -h localhost -p 5432 -U postgres -d mydatabase < mydatabase_backup.sql 注意点: この方法だと、既存のテーブルやデータが上書きされるか、エラーになる場合がある。リストア前にデータベースを空にするか、`DROP DATABASE`してから新しく作るのが安全な場合が多いよ。
`-Fc` (custom format) バックアップを `pg_restore` でリストアする
こっちが、僕が現場でよく使う方法。`pg_dump -Fc` で作った `.dump` ファイルは、`pg_restore` でリストアするんだ。
基本形はこんな感じ。
pg_restore [オプション] -d データベース名 バックアップファイル名
例:
pg_restore -h localhost -p 5432 -U postgres -d mydatabase_restored mydatabase_backup.dump
ポイント:
- `-d` オプションで、リストア先のデータベースを指定する。
- リストア先のデータベースは、事前に作成しておく必要がある。`createdb`コマンドとかでね。
`pg_restore` の便利なオプション
`pg_restore`も、`pg_dump`と同じように、色々なオプションがあるよ。
- 既存のデータを削除してリストアする:
`–clean` オプションを使うと、リストアする前に、同じ名前のオブジェクト(テーブルとか)をDROPしてくれる。
pg_restore –clean -h localhost -p 5432 -U postgres -d mydatabase mydatabase_backup.dump
- テーブルごとに並列でリストアする:
`-j` オプションで並列処理を指定すると、リストアが速くなる!CPUコア数に合わせて指定すると効果的だよ。
pg_restore -j 4 -h localhost -p 5432 -U postgres -d mydatabase mydatabase_backup.dump
(CPUコアが4つある場合)
- 特定のテーブルだけリストアする:
`pg_dump`で `-t` オプションを使った場合、`pg_restore`でも同じように指定できる。
pg_restore -t users -t orders -h localhost -p 5432 -U postgres -d mydatabase mydatabase_backup.dump
- 特定のスキーマだけリストアする:
`pg_dump`で `-n` オプションを使った場合、`pg_restore`でも同じように指定できる。
pg_restore -n public -n analytics -h localhost -p 5432 -U postgres -d mydatabase mydatabase_backup.dump
- リストア対象をインタラクティブに選択する:
`-l` オプションでリストアップしてから、`-L` オプションでリストアしたいものを指定する、なんてこともできる。
# まず、バックアップファイルの内容をリストアップ
pg_restore -l mydatabase_backup.dump > restore_list.txt
# restore_list.txt を編集して、リストアしたいものだけ残す
# (例:不要な行を削除する)
# 編集したリストを使ってリストア
pg_restore -L restore_list.txt -h localhost -p 5432 -U postgres -d mydatabase mydatabase_backup.dump
これはちょっと高度だけど、ピンポイントで復旧したい時にはすごく便利だよ。
リストアテストは「儀式」だ!
ここまでバックアップとリストアの方法を見てきたけど、一番大事なのは、「取ったバックアップで、本当に復旧できるか」を定期的に確認すること!
「バックアップは取ってるけど、一度もリストアしたことない…」なんて状態は、一番危ない。いざという時に「あれ?動かないじゃん!」ってことになりかねないんだ。
- 本番環境と同じ構成のテスト環境を用意する:
- 定期的に、本番のバックアップファイルを使ってリストアを試みる:
- リストアしたデータが、期待通りの状態になっているか確認する:
これを習慣づけることが、データベースエンジニアとしての信頼にも繋がると思うよ。
まとめ:備えあれば憂いなし!
今日は、PostgreSQLの論理バックアップとリストアの基本について、`pg_dump`と`pg_restore`を中心に解説してきたけど、どうだったかな?
- バックアップは「保険」であり、「まさか」に備えるための必須作業。
- `pg_dump`でデータベースを論理バックアップできる。
- `-Fc` (custom format) で圧縮・バイナリ形式でバックアップするのがおすすめ。
- `pg_restore`でバックアップを元に戻せる。
- リストアテストは、必ず定期的に行うべし!
これらの基本的なコマンドを使いこなせるようになれば、PostgreSQLの運用で遭遇するであろう多くのトラブルに対応できるはずだよ。
もちろん、これはあくまで「入門」だから、もっと高度なバックアップ戦略(WALアーカイブとPITRを組み合わせたものとか)もある。でも、まずはこの`pg_dump`と`pg_restore`をしっかりマスターすることが、何よりも大切だと思うんだ。
もし、この記事を読んで「よし、今日からバックアップちゃんとやろう!」って思ってくれたら、僕としては最高に嬉しいな!
また何か質問とかあったら、いつでも聞いてね! じゃあ、また!
コメント