Skip to content
VDS · データベース

データベースのバックアップ

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つのコピーを保持し、ダンプのサイズを監視してください。サイズが急減した場合、データベース全体がダンプされなかったことを意味します。