Ubuntu版のPostgresqlで利用できる pg_backupcluster コマンドでバックアップして、pg_upgradeclusterでバージョンアップ

毎度、ググっても出てこない小ネタを取り扱っております。
本記事は個人的な見解であり、筆者の所属するいかなる団体にも関係ございません。

# 0. はじめに

以下の記事で、pg_**clusterコマンドについて解説したので、このコマンドを使ってバックアップとアップグレードを行ってみます。

Ubuntu版のPostgresqlで利用できる便利な pg\_\*cluster コマンドについて \#PostgreSQL \- Qiita 
https://qiita.com/ynott/items/7d56ecfcdf6fc01c61ee

# 1. バックアップの前にクラスターを確認

以降のコマンドはroot権限で実行してください。

```bash
pg_lsclusters
```
※このコマンドだけ複数形なのに注意してください。

実行結果
```
Ver Cluster Port Status Owner    Data directory              Log file
14  main    5432 online postgres /var/lib/postgresql/14/main log/postgresql-%Y-%m-%d_%H%M%S.log
16  main    5433 online postgres /var/lib/postgresql/16/main /var/log/postgresql/postgresql-16-main.log
```

このマシンは、Ubuntu 22.04 LTSから24.04 LTSでdo-release-upgrade直後なので、Postgresql 14と16が同居しています。

# 2. バックアップしてみる


## 2-1. オプションを確認

pg_backupclusterコマンドを実行しますが、オプションがあります。

```bash
Syntax: /usr/bin/pg_backupcluster [options] <version> <cluster> <action>
Actions:
  createdirectory        Create /var/backups/version-cluster
  basebackup             Backup using pg_basebackup
  dump                   Backup using pg_dump
  expiredumps <N>        Remove all but last N dumps
  expirebasebackups <N>  Remove all but last N basebackups
  receivewal             Launch pg_receivewal
  compresswal            Compress WAL files in archive
  archivecleanup         Remove obsolete WAL files from archive
  list                   Show dumps, basebackups, and WAL
Options:
  -c --checkpoint <spread|fast>  Passed to pg_basebackup
  -k --keep-on-error     Keep faulty backup directory on error
  -v --verbose           Verbose output
```

それぞれどういうオプションなのか確認します。

| アクション | 説明 |
|------------|------|
| createdirectory | `/var/backups/version-cluster` ディレクトリを作成 |
| basebackup | pg_basebackupを使用したバックアップを実行 |
| dump | pg_dumpを使用したバックアップを実行 |
| expiredumps \<N> | 最新のN個のダンプを残して他を削除 |
| expirebasebackups \<N> | 最新のN個のベースバックアップを残して他を削除 |
| receivewal | pg_receivewalを起動してWALを受信 |
| compresswal | アーカイブ内のWALファイルを圧縮 |
| archivecleanup | アーカイブから不要なWALファイルを削除 |
| list | ダンプ、ベースバックアップ、WALの一覧を表示 |

**オプション一覧**

| オプション | 説明 |
|------------|------|
| -c, --checkpoint \<spread\|fast> | pg_basebackupに渡されるチェックポイントオプション<br>- spread: チェックポイントを分散して実行（デフォルト）<br>- fast: チェックポイントを即時実行 |
| -k, --keep-on-error | エラー発生時に問題のあるバックアップディレクトリを保持 |
| -v, --verbose | 詳細な出力を表示 |

注意：この情報はPostgreSQLのバージョンやシステム環境によって実際の動作が異なる可能性があります。

## 2-2. basebackupとdumpについて詳しく

pg_basebackupとpg_dumpの違いについて、主要な特徴を比較します。

**pg_basebackupとpg_dumpの比較表**

| 項目 | pg_basebackup | pg_dump |
|------|---------------|----------|
| バックアップ形式 | 物理バックアップ（データファイルの完全コピー） | 論理バックアップ（SQLステートメント） |
| バックアップ範囲 | クラスタ全体（全データベース） | 単一データベース or 選択したオブジェクト |
| バックアップサイズ | 大きい（データディレクトリ全体） | 比較的小さい（データのみ） |
| リストア速度 | 高速 | データ量に応じて時間がかかる |
| バージョン互換性 | 同一メジャーバージョン内のみ | 異なるバージョン間で移行可能 |
| Point-in-Time Recovery | 可能（WALと組み合わせ） | 不可 |


**使い分けのガイドライン**

1. pg_basebackupを使用するケース
   - 障害復旧用のバックアップ
   - PITRが必要な場合
   - 大規模データベースの高速リストアが必要な場合

2. pg_dumpを使用するケース
   - バージョンアップグレード時
   - 特定のデータのみバックアップが必要な場合
   - 開発環境へのデータ移行
   - 小規模〜中規模データベースのバックアップ

pg_basebackupは、ディレクトリごとバックアップで、pg_dumpはSQL文へのバックアップのようですね。

## 2-2. 現在のバックアップを確認

まだバックアップしてないのですが、バックアップが無いことを確認します。

```
# pg_backupcluster 14 main list
Cluster 14 main backups in /var/backups/postgresql/14-main:
Dumps:
Basebackups:
Total: 0 Bytes
```
## 2-3. basebackupでバックアップを実行

以下のコマンドでバックアップします。
```bash
pg_backupcluster 14 main basebackup
```

実行結果

```bash
# pg_backupcluster 14 main basebackup
Creating backup in /var/backups/postgresql/14-main/2025-02-02T090430Z.backup
pg_basebackup: initiating base backup, waiting for checkpoint to complete
pg_basebackup: checkpoint completed
pg_basebackup: write-ahead log start point: 1/DC000028 on timeline 1
pg_basebackup: starting background WAL receiver
pg_basebackup: created temporary replication slot "pg_basebackup_5446"
112881/112881 kB (100%), 1/1 tablespace
pg_basebackup: write-ahead log end point: 1/DC000138
pg_basebackup: waiting for background process to finish streaming ...
pg_basebackup: syncing data to disk ...
pg_basebackup: renaming backup_manifest.tmp to backup_manifest
pg_basebackup: base backup completed
```

## 2-4. 再度、バックアップを確認

バックアップが保存されました。

```bash
# pg_backupcluster 14 main list
Cluster 14 main backups in /var/backups/postgresql/14-main:
Dumps:
Basebackups:
  /var/backups/postgresql/14-main/2025-02-02T090430Z.backup: 16785402 Bytes
Total: 16785402 Bytes
```

これで、もし失敗しても元に戻せるようになりました。

# 3. Postgresql 14から16へアップグレードする

このアップグレード方法は、以下で説明していたりするので詳細はこちらを確認してください。

Ubuntu 20\.04 LTS へ do\-release\-upgrade した後に Postgresql 10から12にアップグレードした話\(pg\_upgradecluster編\) \#PostgreSQL \- Qiita 
https://qiita.com/ynott/items/281c8b01d2d96468c501

## 3-1. 動いているクラスターを確認する

```bash
pg_lsclusters
```

14と16が動いています。

```
Ver Cluster Port Status Owner    Data directory              Log file
14  main    5432 online postgres /var/lib/postgresql/14/main log/postgresql-%Y-%m-%d_%H%M%S.log
16  main    5433 online postgres /var/lib/postgresql/16/main /var/log/postgresql/postgresql-16-main.log
```

移行先の16は一旦不要(pg_upgradeclusterで再度作成される)ので、削除します。

## 3-2. 移行先の16を削除する

```
pg_dropcluster 16 main --stop
```

::: note info
バージョンを間違えないように注意です。
失敗したら、restoreclusterで戻しましょう
:::

## 3-3. 16が削除されたか確認

```bash
pg_lsclusters
```

削除されました。

```bash
Ver Cluster Port Status Owner    Data directory              Log file
14  main    5432 online postgres /var/lib/postgresql/14/main log/postgresql-%Y-%m-%d_%H%M%S.log
```

## 3-4. 14から16へアップグレード

pg_upgradeclusterコマンドのUsageは以下のようになっていますが、
```
Usage: /usr/bin/pg_upgradecluster [OPTIONS] <old version> <cluster name> [<new data directory>]
```

pg_upgradecluster 古いバージョン番号 クラスター名 -v 新しいバージョン番号
と書けます。
＜旧バージョン＞ ➡ ＜新バージョン＞ の順番が間違えなくてよいと思います。


```bash
pg_upgradecluster 14 main -v 16 
```

## 3-5. クラスターの状態を確認

```bash
pg_lsclusters
```

14がdownになり、16がonlineでポート番号も5432を引き継いでいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/147d7363-186a-e35f-1ffd-fa9a44f77b3c.png)

## 3-6. 動作を確認

アプリケーションの動作を確認します。

## 3-7. 古いPostgresqlのClusterを削除する

```bash
pg_dropcluster 14 main
```

## 3-8. 削除されたか確認

```
pg_lsclusters
```

削除されました。

```
Ver Cluster Port Status Owner    Data directory              Log file
16  main    5432 online postgres /var/lib/postgresql/16/main log/postgresql-%Y-%m-%d_%H%M%S.log
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/04cd85b2-676e-ae86-5d21-0c02f0ea0782.png)

# 4. まとめ

Ubuntu版のPostgresqlは便利なコマンドが追加されているので活用しましょう。

Postgresqlが14から16にバージョンアップしたわけですが、アプリケーションのキビキビ度が格段に上がりました。