#!/usr/bin/env bash # ============================================================= # rman-backup.sh # # Comprehensive RMAN backup script for Oracle databases. # # Schedule: # - Saturday night: Level 0 (full) incremental backup # - All other nights: Level 1 incremental backup # # Policies: # - Archive logs backed up 2 times before deletion # - 15-day recovery window for database files and archive logs # - Compressed backupsets with parallelism 2 # - Controlfile and SPFILE backed up every run # # Maintenance: # - Crosscheck and remove expired/obsolete backups each run # # Usage: # chmod +x rman-backup.sh # # Add to crontab for 11 PM nightly: # # 0 23 * * * /opt/oracle/scripts/rman-backup.sh >> /var/log/oracle/rman-cron.log 2>&1 # # Exit codes: # 0 backup completed successfully # 1 RMAN returned errors # 2 environment setup error # ============================================================= set -uo pipefail # ----- Configuration (override via env) ----- ORACLE_SID="${ORACLE_SID:-FREE}" ORACLE_HOME="${ORACLE_HOME:-/opt/oracle/product/23ai/dbhomeFree}" BACKUP_BASE="${BACKUP_BASE:-/opt/oracle/backup/${ORACLE_SID}}" LOG_DIR="${LOG_DIR:-${BACKUP_BASE}/logs}" NLS_DATE_FORMAT="YYYY-MM-DD HH24:MI:SS" PARALLELISM="${PARALLELISM:-2}" RETENTION_DAYS="${RETENTION_DAYS:-15}" ARCHIVELOG_BACKUP_COPIES="${ARCHIVELOG_BACKUP_COPIES:-2}" export ORACLE_SID ORACLE_HOME NLS_DATE_FORMAT export PATH="$ORACLE_HOME/bin:$PATH" # ----- Setup ----- mkdir -p "$BACKUP_BASE"/{database,archivelog,controlfile,spfile,logs} RUN_DATE=$(date +%Y%m%d) RUN_TS=$(date +%Y%m%d_%H%M%S) LOG_FILE="$LOG_DIR/rman_backup_${RUN_TS}.log" # Determine backup level by day of week (6 = Saturday) DOW=$(date +%u) if [[ $DOW -eq 6 ]]; then LEVEL=0 LEVEL_DESC="FULL_L0" else LEVEL=1 LEVEL_DESC="INCR_L1" fi echo "=============================================" echo "RMAN Backup — $ORACLE_SID" echo "Date: $(date '+%Y-%m-%d %H:%M:%S')" echo "Level: $LEVEL ($LEVEL_DESC)" echo "Log: $LOG_FILE" echo "=============================================" # ----- Validate environment ----- if [[ ! -x "$ORACLE_HOME/bin/rman" ]]; then echo "ERROR: rman not found at $ORACLE_HOME/bin/rman" >&2 exit 2 fi if ! pgrep -f "ora_pmon_${ORACLE_SID}" > /dev/null 2>&1; then echo "ERROR: database instance $ORACLE_SID is not running" >&2 exit 2 fi # ----- Run RMAN ----- rman target / log="$LOG_FILE" </dev/null; then echo "WARNING: RMAN messages found in log. Review $LOG_FILE" exit 1 fi echo "RMAN completed successfully." else echo "RMAN exited with code $RMAN_RC. Review $LOG_FILE" exit 1 fi echo "Backup level: $LEVEL_DESC" echo "Log file: $LOG_FILE" echo "Backup base: $BACKUP_BASE" echo "=============================================" # ----- Cleanup old log files (keep 30 days) ----- find "$LOG_DIR" -name "rman_backup_*.log" -mtime +30 -delete 2>/dev/null exit 0