Docker上のPostgreSQLをバックアップ・リストア方式でアップグレードする
PostgreSQLがローカルマシンに直接インストールされている場合、pg_upgrade を実行すれば良いのですが、Dockerで動いているPostgreSQLをアップグレードする方法に迷いました。手順を本稿にメモしておきます。
TL;DR
Webの翻訳支援システムである Weblate はOSSとして展開しており、コントリビューションガイドの一環で Docker上の PostgreSQL をアップグレードする記述がありました。今回はこちらを拝借して自分の環境で試したので、同じ手順です。バックアップ・アップグレード・リストアの順で実行します。
環境
ローカルマシンの環境です。
- M1 Mac Monterey
- Docker for Mac
- docker compose でPostgreSQLを利用
- PostgreSQL11 => 14へ上げたい
PostgreSQL のバージョンを変えただけでは、エラーになる
このように docker-compose.yml
を変えますが...
version: "3"
volumes:
db-data:
services:
db:
- image: postgres:11
+ image: postgres:14
container_name: db
volumes:
- db-data:/var/lib/postgresql/db_development/data
ports:
- "5432:5432"
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
互換性がないので起動できません。
docker compose up
db |
db | PostgreSQL Database directory appears to contain a database; Skipping initialization
db |
db | 2022-10-28 05:53:15.039 UTC [1] FATAL: database files are incompatible with server
db | 2022-10-28 05:53:15.039 UTC [1] DETAIL: The data directory was initialized by PostgreSQL version 11, which is not compatible with this version 14.0
db exited with code 1
いくつか選択肢がある
DockerのPostgreSQLバージョンをあげるには、いくつか選択肢があります。
- これまでのデータをあきらめて、ボリュームとコンテナを再作成する
- 有志による docker-postgres-upgrade を使う
- バックアップ・アップグレード・リストアの順で実行する(本稿)
1は、ローカル開発ならありえる選択肢です。すべてのデータがseedなどで再作成できるならば、確実な方法です。2は、素敵なツールが公開されているのですが、実行したときに
could not open version file "/var/lib/postgresql/11/data/PG_VERSION": No such file or directory
のように言われてしまい、結局そこで終わっています。少しチューニングすれば実行できるのかもしれませんが、あきらめました。以降は3について述べます。
バックアップ・アップグレード・リストアの手順
Weblateのコントリビューションガイドを参考にしています。なお、ユーザー名などは、
設定名 | 設定値 |
---|---|
ユーザー名 | postgres |
パスワード | password |
以上の前提で進めます。
DBバックアップ
古いバージョンのPostgreSQL(今回は11)で実行します。
# まず起動
docker compose up -d
# バックアップをとる
docker-compose exec db pg_dumpall --clean --username postgres > backup.sql
# データベース コンテナの停止:
docker compose stop
ボリュームを削除
docker-compose rm -v db
docker volume ls # 削除するボリューム名を特定
docker volume remove app_db-data
アップグレード
新しい PostgreSQL のバージョンを使用するように :file:docker-compose.yml
を編集します。
version: "3"
volumes:
db-data:
services:
db:
- image: postgres:11
+ image: postgres:14
container_name: db
...(後略)
docker-compose.yml を編集した状態で起動します。
docker compose up -d
# バックアップファイルからリストア
cat backup.sql | docker-compose exec -T db psql --username postgres
パスワードを再設定
PostgreSQL11から14へアップグレードする場合、パスワードのハッシュ化アルゴリズムが変わっているため、再設定します。
docker exec -it app_db bash
> su postgres
> psql
> \password postgres;
Enter new password for user "postgres":
==> password <Enter>
これでアプリやSQLクライアントから接続できるようになるはずです。
Discussion