DB のバックアップと復元確認のスクリプトを追加(NAS の DSM タスクスケジューラ用)

This commit is contained in:
2026-10-04 16:03:54 +09:00
parent d4346c06fe
commit fb3e128757
6 changed files with 733 additions and 6 deletions
+73
View File
@@ -0,0 +1,73 @@
#!/bin/bash
# tver DB復元確認(Synology ds923pで手動実行)
#
# 配置先: /volume1/docker/tver-db/restore-test.sh
# 実行コマンド: bash /volume1/docker/tver-db/restore-test.sh
# 最新のバックアップを同じPostgreSQLコンテナ内の一時DBへ復元し、主要4表の
# 行数を本番DBと比較する。本番DBにはSELECTだけを実行する。
set -euo pipefail
BACKUP_DIR="${BACKUP_DIR:-/volume1/backups/tver}"
LOG_FILE="${LOG_FILE:-${BACKUP_DIR}/restore-test.log}"
CONTAINER="${CONTAINER:-tver-postgres}"
DB_USER="${DB_USER:-tver}"
DB_NAME="${DB_NAME:-tver}"
RESTORE_DB="${RESTORE_DB:-tver_restore_test}"
DOCKER="${DOCKER:-$(command -v docker || printf '/usr/local/bin/docker')}"
TABLES=(download_jobs subscriptions known_episodes schema_migrations)
mkdir -p "$BACKUP_DIR"
touch "$LOG_FILE"
chmod 600 "$LOG_FILE"
exec > >(tee -a "$LOG_FILE") 2>&1
if [[ "$RESTORE_DB" == "$DB_NAME" ]]; then
echo "ERROR: RESTORE_DB must differ from DB_NAME" >&2
exit 1
fi
# 終了状態にかかわらず、一時DBの削除を最後に試みる。
cleanup() {
status=$?
trap - EXIT
set +e
"$DOCKER" exec "$CONTAINER" dropdb --force --if-exists -U "$DB_USER" "$RESTORE_DB"
cleanup_status=$?
if ((status != 0)); then
echo "復元確認に失敗"
exit "$status"
fi
exit "$cleanup_status"
}
trap cleanup EXIT
LATEST="$(find "$BACKUP_DIR" -name 'tver_*.sql.gz' -type f -print | sort | tail -n 1)"
if [[ -z "$LATEST" ]]; then
echo "ERROR: backup dump was not found in $BACKUP_DIR" >&2
exit 1
fi
echo "復元確認を開始: $LATEST"
"$DOCKER" exec "$CONTAINER" dropdb --force --if-exists -U "$DB_USER" "$RESTORE_DB"
"$DOCKER" exec "$CONTAINER" createdb -U "$DB_USER" "$RESTORE_DB"
gzip -dc "$LATEST" \
| "$DOCKER" exec -i "$CONTAINER" psql -q -o /dev/null -v ON_ERROR_STOP=1 -U "$DB_USER" -d "$RESTORE_DB"
for table in "${TABLES[@]}"; do
query="SELECT count(*) FROM public.${table};"
production_count="$("$DOCKER" exec "$CONTAINER" psql -A -t -q -U "$DB_USER" -d "$DB_NAME" -c "$query" | tr -d '[:space:]')"
restored_count="$("$DOCKER" exec "$CONTAINER" psql -A -t -q -U "$DB_USER" -d "$RESTORE_DB" -c "$query" | tr -d '[:space:]')"
if [[ ! "$production_count" =~ ^[0-9]+$ || ! "$restored_count" =~ ^[0-9]+$ ]]; then
echo "ERROR: $table の行数を取得できませんでした: production=$production_count restore=$restored_count" >&2
exit 1
fi
if [[ "$production_count" != "$restored_count" ]]; then
echo "ERROR: $table の行数が一致しません: production=$production_count restore=$restored_count" >&2
exit 1
fi
echo "OK: $table production=$production_count restore=$restored_count"
done
echo "復元確認に成功: $LATEST"