Zeabur のデータベースのバックアップと復元:PostgreSQL・MySQL・MongoDB・Redis の検証済みコマンド

Zeabur からデータベースを持ち出す 2 つの方法、標準バックアップと自分での dump。すべてのコマンドを Docker で実際に実行し、遭遇するエラーメッセージもあわせて載せています。

要点

  • pg_dump のバージョンは DB サーバーと同じかそれ以上でないと、処理が中止される。
  • Neon や Supabase などのマネージド DB に復元するときは --no-owner --no-acl を付ける。付けないと role "root" does not exist になる。
  • Zeabur 標準バックアップの data.sql は superuser のある DB にしか復元できず、古いパスワードまで復元される。
  • MySQL・MongoDB・Redis のコマンドも検証済み。Redis をキャッシュとしてだけ使っているなら移行は不要。
この記事の検証方法(実機検証 5 件、公式ドキュメント準拠 2 件)
実際に検証した内容
  • PostgreSQL 16 → 17:pg_dump -Fc / pg_restore で superuser ではない DB(Neon/Supabase を想定)に復元。500 件のデータとシーケンスがすべて正しい
  • PostgreSQL:pg_dumpall で作成した data.sql(Zeabur 標準バックアップと同じ形式)を、セルフマネージドとマネージドの両方の DB に復元
  • MySQL 8:ストアドプロシージャとトリガーを含む mysqldump のバックアップと復元
  • MongoDB 7:mongodump / mongorestore(archive + gzip)
  • Redis 7:redis-cli --rdb で書き出し、新しい Redis で読み込み
公式ドキュメントに基づく内容(未検証)
  • Zeabur の「Backup」タブと「Instruction」タブ:Zeabur 公式ドキュメントに基づいて記載。Zeabur での操作は行っていません
  • 検証は Zeabur のデータベースを模した Docker コンテナ(superuser 名も root)で行っており、実際の Zeabur ホストには接続していません
目次(7 項目)
  1. まず知っておくこと:Zeabur には標準バックアップがあるが、それだけでは足りないことも
  2. 接続情報の場所
  3. PostgreSQL
  4. MySQL / MariaDB
  5. MongoDB
  6. Redis
  7. 復元後に必ずやること

まず知っておくこと:Zeabur には標準バックアップがあるが、それだけでは足りないことも

Zeabur のドキュメントによると、データベースサービスの「Backup」タブで「Backup」ボタンを押すと、数分でダウンロードできるようになります。この機能は有料プラン(Dev プラン以上)限定で、バックアップは 7 日間保持された後に自動削除されます。

データベースZeabur 標準バックアップの形式復元に使うもの
PostgreSQLpg_dumpall による .sql。サービス内の全データベースを含むpsql
MySQL / MariaDB.sql。システム以外の全データベースを含むmysql
MongoDB複数の .bson ファイルmongorestore

おすすめ:標準バックアップをダウンロードしたうえで、下のコマンドで自分でももう 1 つ取っておく。 理由は PostgreSQL の節で説明しますが、マネージド DB へ移る場合、標準バックアップの形式ではエラーになります。

接続情報の場所

Zeabur の PostgreSQL テンプレートの説明によると、データベースサービスの「Instruction」タブにある「Public (External)」セクションに、外部接続用の Connection String と接続コマンドがあります。ホスト名は hkg1.clusters.zeabur.com のような形で、ポートは Zeabur が割り当てた番号です。

末尾が zeabur.internal のホスト名は Zeabur 内部専用で、手元のパソコンからは接続できません。

以下のコマンドはすべて Docker で実行するので、ローカルにデータベースツールをインストールする必要はありません。

PostgreSQL

1. まずサーバーのバージョンを確認

docker run --rm postgres:17 psql "postgresql://USER:PASS@HOST:PORT/DB" -tAc "show server_version"

pg_dump のバージョンはサーバーと同じかそれ以上である必要があります。 バージョン 15 の pg_dump でバージョン 16 のサーバーをバックアップすると、すぐに中止されました。

pg_dump: error: aborting because of server version mismatch
pg_dump: detail: server version: 16.15 ...; pg_dump version: 15.19 ...

そのため、下のイメージのバージョン(postgres:16)は、サーバーと同じかそれより新しいメジャーバージョンに置き換えてください。

2. バックアップ(custom 形式がおすすめ)

docker run --rm -v "$PWD:/out" postgres:16 \
  pg_dump "postgresql://USER:PASS@HOST:PORT/DB" -Fc -f /out/backup.dump

3. Neon や Supabase などのマネージド DB に復元

マネージド DB で使えるアカウントは superuser ではなく、Zeabur 上のテーブルの所有者は root です。そのまま復元すると次のエラーになります。

pg_restore: error: could not execute query: ERROR:  role "root" does not exist

--no-owner --no-acl を付ければ回避できます。検証ではエラーゼロ、件数も正しく、新しく挿入した id も元のシーケンスから正しく続きました。

docker run --rm -v "$PWD:/out" postgres:17 \
  pg_restore --no-owner --no-acl -d "新しいDBの接続文字列" /out/backup.dump

Zeabur 標準バックアップの data.sql で復元する場合

Zeabur のドキュメントでは、解凍してから次を実行する手順になっています。

psql -h ホスト -p ポート -U ユーザー postgres < data.sql

同じ形式(pg_dumpall)で検証した結果:

  • 自分で管理する PostgreSQL(superuser あり)への復元:成功、データも完全
  • マネージド DB(superuser なし)への復元:失敗、ERROR: permission denied to alter role が出ます。この場合は上の pg_dump -Fc を使ってください

セキュリティ上の注意: data.sql の冒頭には次の 2 行があります。

CREATE ROLE root; ALTER ROLE root WITH SUPERUSER ... PASSWORD 'SCRAM-SHA-256$...';

つまり、復元するとデータベースのパスワードが Zeabur 上の古いパスワードに戻ります。Zeabur ではセキュリティインシデントが起きているので、復元後すぐにパスワードを変更してください。

ALTER ROLE root WITH PASSWORD '新しい長いパスワード';

Zeabur のドキュメントにも、現在のパスワードを維持したい場合は復元前に data.sql から CREATE ROLE と ALTER ROLE の行を削除できると書かれています。

バックアップの検証(5 分、強く推奨)

ローカルで空のデータベースを起動し、バックアップを復元して、テーブルと件数を確認します。

docker network create restore-net
docker run -d --name restore-test --network restore-net -e POSTGRES_PASSWORD=x postgres:17
# データベースの起動を数秒待つ
docker run --rm --network restore-net -v "$PWD:/out" postgres:17 \
  pg_restore --no-owner --no-acl -d "postgresql://postgres:x@restore-test:5432/postgres" /out/backup.dump
docker exec restore-test psql -U postgres -tAc "select count(*) from テーブル名"

# 確認が終わったら片付ける
docker rm -f restore-test && docker network rm restore-net

なぜ -p 5433:5432 でポートを公開しないのか? 最初の検証ではそう書いていましたが、検証用マシンの 5433 番ポートでたまたま別のローカル PostgreSQL が動いていて、バックアップがそちらに復元されてしまいました。Docker ネットワークを使えば検証用 DB は外部にポートを公開しないので、接続先を間違えることがありません。

MySQL / MariaDB

# バックアップ:--single-transaction でテーブルをロックせず、--routines --triggers でストアドプロシージャとトリガーも含める
docker run --rm -v "$PWD:/out" mysql:8 sh -c \
  'mysqldump -h HOST -P PORT -u USER -pPASS --single-transaction --routines --triggers DB > /out/backup.sql'

# 復元
docker run --rm -v "$PWD:/out" mysql:8 sh -c 'mysql -h 新HOST -P 新PORT -u USER -pPASS DB < /out/backup.sql'

検証結果:データ、ストアドプロシージャ 1 つ、トリガー 1 つがすべて移行できました。

MongoDB

docker run --rm -v "$PWD:/out" mongo:7 \
  mongodump --uri "mongodb://USER:PASS@HOST:PORT/?authSource=admin" --archive=/out/backup.archive --gzip

docker run --rm -v "$PWD:/out" mongo:7 \
  mongorestore --uri "新しい接続文字列" --archive=/out/backup.archive --gzip

検証時の出力:50 document(s) restored successfully. 0 document(s) failed to restore.

Redis

Redis をキャッシュとしてだけ使っているなら、移行する必要はありません。新しい Redis が動き始めればキャッシュは自然に作り直されます。キューやランキングなど、本当にデータを Redis に保存している場合は次のとおりです。

docker run --rm -v "$PWD:/out" redis:7 redis-cli -h HOST -p PORT -a PASS --rdb /out/dump.rdb

成功すると Transfer finished with success と表示されます。dump.rdb を新しい Redis のデータディレクトリ(公式イメージでは /data)に置いて起動すれば、自動で読み込まれます。検証ではキーの数が一致しました。

復元後に必ずやること

  • 新しい接続文字列(DATABASE_URL など)に切り替え、データベースのパスワードを変更する
  • 重要なテーブルをいくつか選んで件数を照合する
  • 新しいプラットフォームで毎日の自動バックアップを有効にし、実際に一度ダウンロードして取り出せることを確認する

よくある質問

Zeabur にデータベースの標準バックアップ機能はありますか?

あります。データベースサービスの「Backup」タブからダウンロードできますが、有料プラン限定で、保持期間は 7 日間です。PostgreSQL のバックアップは pg_dumpall で作成された .sql ファイルです。

復元時に role "root" does not exist と出るのはなぜですか?

Zeabur 上のテーブルの所有者は root ですが、マネージド DB にはそのロールがありません。pg_restore に --no-owner --no-acl を付ければ回避でき、検証ではエラーゼロでした。