PostgreSQLの論理バックアップのユースケース

## はじめに

こんにちは！[ラクス Advent Calendar 2024](https://qiita.com/advent-calendar/2024/rakus)に参加している1年目のエンジニアです！
みなさんはPostgreSQLを使っていますか？バックアップを取る必要があったときのために、バックアップ手法の一つである論理バックアップについて様々なユースケースごとにまとめました！:v:
みなさんの開発、運用の一助になりますと幸いです:pray:

バックアップには大きく分けて「論理バックアップ」と、「物理バックアップ」の2種類があります。この記事では、とりわけ「論理バックアップ」を使用した方法について解説します。


## 論理バックアップの種類
論理バックアップでは、バックアップしたいデータやユースケースによって以下のようなコマンドを使い分けます。
- `pg_dumpall`コマンド
データベースクラスタ全体の内容をバックアップする。取得したバックアップデータは、`psql`コマンドでリストアできる。

- `pg_dump`コマンド
指定したデータベースの内容をバックアップする。スクリプト形式であれば`psql`コマンド、アーカイブファイル形式のバックアップデータは`pg_restore`コマンドを使ってリストアできる。

- SQLコマンドの`COPY`
指定したテーブルデータを独自のテキスト形式かバイナリー形式、CSV形式でバックアップする。取得したバックアップデータは、COPYを使ってリストアできる。


## 論理バックアップの手順
今回はある**データベース**をバックアップ、リストアしたい場合の手順を追ってみましょう。

### **手順**
① **`pg_dump`のコマンドでバックアップファイルを作成**
   以下は、基本的な`pg_dump`コマンドの使用例です。

   ```bash
   pg_dump -U <ユーザー名> [オプション] <データベース名>
   ```
   また、以下のようなオプションをつけられます。
   
| オプション  | 説明         |
| ----------- | ----------------------------------------- |
| `-h`        | PostgreSQLサーバーのホスト名。                              |
| `-U`        | バックアップを取得するためのユーザー名（通常は`postgres`）。 |
| `-Fc`      | カスタムフォーマットでバックアップを取得。                  |
| `-b`        | 大きなオブジェクト（バイナリデータ）も含める。              |
| `-v`        | 詳細な出力を有効化。                                       |
| `-f`        | バックアップファイルの保存先。                              |

   
   例えばローカルのsampleというDBのバックアップを、実行ユーザpostgresとして指定ディレクトリにカスタム形式で保存したい場合は以下のようになります。
   ```bash
   pg_dump -h localhost -U postgres -Fc -f usr/db/dumpdir/sample_backup.dump sample
   ```


② **pg_restoreでリストアを実行**
 以下は、基本的な`pg_restore`コマンドの使用例です。
```bash
pg_restore -U <ユーザー名> -d <リストア先データベース名> [オプション] <バックアップファイル名>
 ```

   例えばローカルのsampleというDBのバックアップを、実行ユーザpostgresとしてリストアしたい場合は以下のようになります。
```bash
pg_restore -h localhost -U postgres -d sample usr/db/dumpdir/sample_backup.dump
```

   また、以下のようなオプションをつけられます。

| オプション             | 説明                                       |
| ------------------------   | ------------------------------------------ |
| `-d`                | リストア先のデータベース名を指定                     |
| `-h`                | 接続先ホスト名を指定                             |
| `-U`                | PostgreSQLユーザー名を指定                      |
| `-v`                | 詳細な進行状況を表示                             |
| `-l`                | バックアップファイルの内容をリストとして表示             |
| `-t <テーブル名>`    | 特定のテーブルだけをリストア                         |
| `-n <スキーマ名>`    | 特定のスキーマだけをリストア                         |
| `--data-only`       | データのみをリストア                             |
| `--schema-only`     | スキーマ（構造）のみをリストア                      |
| `--clean`           | リストア前に既存のオブジェクトを削除                  |
| `--if-exists`       | 削除オプションで対象が存在する場合のみ削除を実行          |


# 各ユースケースにおけるバックアップ方法
以下では、様々なユースケースに応じた論理バックアップの方法をまとめています。

## ケース① 特定のスキーマだけバックアップしたいとき

`pg_dump`で`-n`オプションを使用すれば、特定のスキーマだけをバックアップすることが可能です。

### **コマンド例**
```bash
pg_dump -U <ユーザー名> -Fc -n <スキーマ名> -f <バックアップファイル名> <データベース名>
```


## ケース② 特定のスキーマの特定のテーブルだけバックアップしたいとき

`pg_dump`で`-t`オプションを使用すれば、特定のスキーマの特定のテーブルだけをバックアップすることが可能です。


### **コマンド例**
```bash
pg_dump -U <ユーザー名> -Fc -n <スキーマ名> -t <テーブル名> -f <バックアップファイル名> <データベース名>
```

### 補足
- テーブルは`<スキーマ名>.<テーブル名>`の形式で指定することも可能です。


## ケース③ 特定のスキーマの特定のテーブルの中身だけバックアップしたいとき

特定のテーブルのデータだけをバックアップするには、 `--data-only`オプションを用います。

### **コマンド例**
```bash
pg_dump -U <ユーザー名> -Fc --data-only -n <スキーマ名> -t <テーブル名> -f <バックアップファイル名> <データベース名>
```

### 補足
- リストアの際は、バックアップしたテーブルがすでにつくられていること、バックアップしたデータとリストア先のテーブルの中身に重複がないことはチェックしておきましょう。




## ケース④ 自分が指定した条件に合うデータのみを抽出してバックアップしたいとき
事前に条件を設定した**ビュー**を作成することで、バックアップ対象を絞ることが可能です。

### **コマンド例**
```sql
-- 登録日が2024年のデータのみ抽出
CREATE VIEW filtered_data AS
SELECT * FROM <テーブル名>
WHERE register_date BETWEEN '2024-01-01' AND '2024-12-31';
```

作成したビューを`-t`オプションで指定します。

### **コマンド例**
```bash
pg_dump -U <ユーザー名> -Fc -t filtered_data -f <バックアップファイル名> <データベース名>
```


## まとめ
今回ご紹介したように、ダンプ取得時は様々なオプションやビューを用いて自分の行いたいケースに応じたバックアップが行えるようになっています。個人的にはケース②がテーブルに変更を加えるようなテストをする際に便利だと感じています！ケース④は今回の記事を書いている際に初めて知ることができました。dumpファイルの中身はSQL文なので、中身をみて大体こういうデータが入っているんだなと判断できます(案外そこの仕組みは単純でびっくりしました)。
ぜひ論理バックアップを使いこなせるようにしましょう！



## 参考文献
[FIJITSU - 技術を知る：PostgreSQLのバックアップとリカバリー ～ 論理バックアップ ～](https://www.fujitsu.com/jp/products/software/resources/feature-stories/postgres/article-index/logical-backup/)

[EnterpriseZine - 論理バックアップはDBバックアップとして適切か？](https://enterprisezine.jp/article/detail/9512)

[IBM - 論理バックアップとリストア](https://www.ibm.com/docs/ja/db2/12.1?topic=recovery-logical-backup-restore)

[NTT - PostgreSQLバックアップ実践とバックアップ管理ツールの紹介](chrome-extension://efaidnbmnnnibpcajpcglclefindmkaj/https://www.postgresql.jp/sites/default/files/2021-11/jpug-pgcon2021-backup_20211112_.pdf)