データベースのバックアップ
MySQLとPostgreSQLのダンプをスケジュールし、マシン外に移動し、バックアップが実際に復元できることを確認する方法を説明します。
更新日 2026年8月23日
VPSには自動のマシンバックアップや状態スナップショットは付属しません。自分でコピーしていないものはすべて単一のインスタンス上にしか存在しません。まず最初に設定すべきはデータベースのダンプです。データを復元する場所がほかにないためです。一方、サイト自体はゼロから再デプロイできます。
手動ダンプ
PostgreSQL:
pg_dump -Fc -U shop -h 127.0.0.1 shop > /srv/backups/shop-$(date +%F).dump
pg_dumpall -U postgres --roles-only > /srv/backups/roles.sql
MySQLとMariaDB:
mysqldump --single-transaction --quick --routines --events \
-u root shop | gzip > /srv/backups/shop-$(date +%F).sql.gz
--single-transactionはテーブルをロックせずに一貫性のあるInnoDBダンプを取得します。これがないと、エクスポート中にサイトが停止します。PostgreSQLの-Fc形式は圧縮され、個別のテーブルを復元できます。
パスワードをコマンドラインに書かないでください。~/.pgpassまたは~/.my.cnfをパーミッション600で作成します。
スケジュール実行
mkdir -p /srv/backups && chmod 700 /srv/backups
crontab -e
20 3 * * * /usr/local/bin/db-backup.sh >> /var/log/db-backup.log 2>&1
/usr/local/bin/db-backup.shスクリプト:
#!/bin/bash
set -euo pipefail
DEST=/srv/backups
STAMP=$(date +%F-%H%M)
pg_dump -Fc -U shop -h 127.0.0.1 shop > "$DEST/shop-$STAMP.dump.tmp"
mv "$DEST/shop-$STAMP.dump.tmp" "$DEST/shop-$STAMP.dump"
find "$DEST" -name '*.dump' -mtime +14 -delete
一時ファイルに書き込んでからリネームすることが重要です。ダンプが中断された場合、切り詰められたファイルを完全なバックアップと誤認しなくなります。set -euo pipefailは最初のエラーでスクリプトを停止し、黙って続行しません。
バックアップをマシンの外に移動する
同じディスク上のコピーでは、移行ミス、ランサムウェア、「アクセス」タブでのOS再インストールからあなたを守れません。ダンプを外部に送信します:
rsync -az --delete /srv/backups/ backup@other-host:/store/vds/
またはrclone経由で任意のS3互換ストレージへ。最大500 Mbit/sの帯域幅と、ティアごとのディスク書き込み制限(コアあたり60 MB/s)に注意してください。
復元チェック
一度も復元したことのないバックアップはバックアップではありません。
createdb -U postgres shop_check
pg_restore -U postgres -d shop_check /srv/backups/shop-2026-08-23.dump
psql -U postgres -d shop_check -c "SELECT count(*) FROM users;"
dropdb -U postgres shop_check
MySQLの場合: gunzip -c dump.sql.gz | mysql -u root shop_check。
これを月に一度行い、チェック日を記録します。
よくある間違い
| 症状 | 原因 |
|---|---|
| ダンプが数キロバイトしかない | スクリプトが認証で失敗し、エラーが/dev/nullに送られた |
| ディスク容量が不足した | mtimeによる古いバックアップの削除がない |
| 復元がパーミッションで失敗する | ロールがダンプされていない — --roles-onlyが必要 |
| Cronが沈黙し、バックアップがない | CronにPATHがない — 絶対パスを使用する |
| 夜間にサイトが遅くなる | ダンプがディスクを奪い合っている — 時間をずらし、--quickを追加する |
異なる場所に少なくとも2つのコピーを保持し、ダンプのサイズを監視してください。サイズが急減した場合、データベース全体がダンプされなかったことを意味します。