【実務・中級編】 バックアップとリストアの基礎 – PostgreSQL

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`をしっかりマスターすることが、何よりも大切だと思うんだ。

もし、この記事を読んで「よし、今日からバックアップちゃんとやろう!」って思ってくれたら、僕としては最高に嬉しいな!

また何か質問とかあったら、いつでも聞いてね! じゃあ、また!

コメント

タイトルとURLをコピーしました