PostgerSQL Periodic backup
2025-08-05
Alright — here’s the improved hourly backup script using pg_dump -Fc (custom format), storing as .dump, without extra gzip, plus logging restore instructions.
pg_backup_user_comments.sh
#!/bin/bash
# ===== CONFIG =====
REMOTE_HOST="ma" # SSH host alias
REMOTE_DB_USER="postgres" # PostgreSQL DB user
DB_NAME="user_comments" # Database name
BACKUP_DIR="$HOME/pg_backups" # Local backup directory
LOG_FILE="$HOME/pg_backups/backup.log"
MAX_BACKUPS=12 # Keep last N backups
DATE_STR=$(date +"%Y-%m-%d_%H-%M-%S")
BACKUP_FILE="${BACKUP_DIR}/${DB_NAME}_${DATE_STR}.dump"
# ===== PREPARE =====
mkdir -p "$BACKUP_DIR"
touch "$LOG_FILE"
echo "[$(date '+%F %T')] Starting backup..." >> "$LOG_FILE"
# ===== BACKUP =====
if ssh "$REMOTE_HOST" "sudo -u postgres pg_dump -Fc -d $DB_NAME" > "$BACKUP_FILE"; then
echo "[$(date '+%F %T')] Backup successful: $BACKUP_FILE" >> "$LOG_FILE"
echo "[$(date '+%F %T')] Restore example: pg_restore -d $DB_NAME $BACKUP_FILE" >> "$LOG_FILE"
else
echo "[$(date '+%F %T')] ERROR: Backup failed" >> "$LOG_FILE"
exit 1
fi
# ===== CLEANUP OLD BACKUPS =====
BACKUP_COUNT=$(ls -1t "$BACKUP_DIR"/*.dump 2>/dev/null | wc -l)
if [ "$BACKUP_COUNT" -gt "$MAX_BACKUPS" ]; then
TO_DELETE=$((BACKUP_COUNT - MAX_BACKUPS))
OLD_BACKUPS=$(ls -1t "$BACKUP_DIR"/*.dump | tail -n "$TO_DELETE")
echo "[$(date '+%F %T')] Removing old backups:" >> "$LOG_FILE"
echo "$OLD_BACKUPS" >> "$LOG_FILE"
rm -f $OLD_BACKUPS
fi
echo "[$(date '+%F %T')] Backup process completed." >> "$LOG_FILE"
Restore Example
From the log or manually:
pg_restore -d user_comments /path/to/user_comments_2025-08-07_14-00-00.dump
You can also restore to another DB:
createdb new_db
pg_restore -d new_db /path/to/backup.dump
Restore only one table:
pg_restore -d target_db -t articles /path/to/backup.dump
Setup Cron (hourly)
crontab -e
Add:
0 * * * * /home/your_user/pg_backup_user_comments.sh
This keeps last 12 hourly backups, logs the restore command each time, and uses pg_dump -Fc so you get all the benefits of custom format.
If you want, I can also make this script automatically restore to a test database once a day so you know backups are valid. That’s something many production setups do for safety. Do you want me to add that automatic restore verification?