#!/bin/ksh # ==================================================================================================== # Title: RMAN_DB_Backup.ksh # Author: Richard Wilson # Date: 03.04.2014 # File Name: RMAN_DB_Backup_v15.ksh # Description: Uses RMAN to backup Oracle databases. # Usage: Usage: RMAN_DB_backup.ksh # # History: # 17.04.2014 RW Added %d%m%Y to Tag. # 24.07.2014 RW Added email notification. # 29.07.2014 RW Added more logic - email after 'backup backup'. # 26.09.2014 RW Included parameter Retention Period. # 03.12.2014 RW Changed to use R5DISK for UAT, SIT & TRAIN. # 11.05.2015 RW Removed Full backups, added Incremental backups. # 09.02.2016 RW Added function 'is_RMAN_running'. # 09.02.2016 RW Added backup 'NOT BACKED UP 2 TIMES' to capture any missed backupsets. # 25.04.2017 RW Added 'Day' input parameter and 'is_day_valid' function. # 10.05.2017 RW Added Level-0 Backup Day input parameter. # 10.05.2017 RW Moved CROSSCHECKS into Level-0 only. # 12.12.2017 RW Added 'is_not_guarded' function to allow backup on STANDBY. # 21.12.2017 RW Added dbhome_1/db_1 logic for ORACLE_HOME. # ----------------------------------------------------------------------------------------------------- function is_fs_mounted { mount | grep "${BACKUP_FS}" > /dev/null && return 0 || return 1 } function is_sid_valid { if [ `ps -ef | grep -v grep | grep "ora_pmon_${ORACLE_SID}$" | wc -l 2> /dev/null` -eq 0 ] then return 1 else return 0 fi } function is_day_valid { case "${LEVEL_0_DAY}" in MON|TUE|WED|THU|FRI|SAT|SUN|ZZZ) return 0;; *) return 1;; esac } function is_RMAN_running { return `${ORACLE_HOME}/bin/sqlplus -S / "as sysdba" <<-EOF set pagesize 0 feedback off verify off heading off termout off echo off select count(1) from sys.v\\$RMAN_STATUS where status like 'RUNNING%'; EOF` } function is_not_guarded { return `${ORACLE_HOME}/bin/sqlplus -S / "as sysdba" <<-EOF set pagesize 0 feedback off verify off heading off termout off echo off select count(1) from sys.v\\$archive_dest where status = 'VALID' and target = 'STANDBY'; EOF` } set_asm_dest() { case "${ORACLE_SID}" in SIT2|DMSIT|IFCE|SYSTST|SYSTST2|GOLD|GOLD2|PACK|PACK2|UPK) asm_disk="+R5DISK";; *) asm_disk="+FRA";; esac } build_cmdfile() { # Build RMAN command file. echo "connect target / " > ${RMAN_CMD_FILE} echo "connect catalog rcatadm/RCATADM@RCAT" >> ${RMAN_CMD_FILE} echo "run {" >> ${RMAN_CMD_FILE} echo "sql 'alter session set optimizer_mode=RULE';" >> ${RMAN_CMD_FILE} echo "resync catalog;" >> ${RMAN_CMD_FILE} echo "sql 'ALTER SYSTEM SET CONTROL_FILE_RECORD_KEEP_TIME=60 SCOPE=BOTH';" >> ${RMAN_CMD_FILE} echo "CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF ${RETENTION_DAYS} DAYS;" >> ${RMAN_CMD_FILE} if is_not_guarded then #P!DG [ "${DEBUG}" == "Y" ] && echo -e "DEBUG: is_not_guarded: PRIMARY - NODG" #echo "CONFIGURE ARCHIVELOG DELETION POLICY TO BACKED UP 1 TIMES TO DISK COMPLETED BEFORE 'SYSDATE-1';" >> ${RMAN_CMD_FILE} echo "CONFIGURE ARCHIVELOG DELETION POLICY TO NONE;" >> ${RMAN_CMD_FILE} else #P+DG [ "${DEBUG}" == "Y" ] && echo -e "DEBUG: is_guarded: PRIMARY - DG" echo "CONFIGURE ARCHIVELOG DELETION POLICY TO BACKED UP 1 TIMES TO DISK APPLIED ON ALL STANDBY;" >> ${RMAN_CMD_FILE} # echo "CONFIGURE ARCHIVELOG DELETION POLICY TO NONE;" >> ${RMAN_CMD_FILE} fi # echo "CONFIGURE ARCHIVELOG DELETION POLICY TO BACKED UP 1 TIMES TO DISK;" >> ${RMAN_CMD_FILE} # echo "CONFIGURE ARCHIVELOG DELETION POLICY TO NONE;" >> ${RMAN_CMD_FILE} # echo "CONFIGURE ARCHIVELOG DELETION POLICY TO BACKED UP 1 TIMES TO DISK APPLIED ON ALL STANDBY;" >> ${RMAN_CMD_FILE} # echo "CONFIGURE ARCHIVELOG DELETION POLICY TO BACKED UP 1 TIMES TO DISK COMPLETED BEFORE 'SYSDATE-1';" >> ${RMAN_CMD_FILE} # echo "CONFIGURE ARCHIVELOG DELETION POLICY TO APPLIED ON ALL STANDBY;" >> ${RMAN_CMD_FILE} echo "CONFIGURE CONTROLFILE AUTOBACKUP ON;" >> ${RMAN_CMD_FILE} echo "CONFIGURE CONTROLFILE AUTOBACKUP FORMAT FOR DEVICE TYPE DISK CLEAR;" >> ${RMAN_CMD_FILE} set_asm_dest echo "ALLOCATE CHANNEL disk1 DEVICE TYPE DISK FORMAT '${asm_disk}';" >> ${RMAN_CMD_FILE} echo "ALLOCATE CHANNEL disk2 DEVICE TYPE DISK FORMAT '${asm_disk}';" >> ${RMAN_CMD_FILE} echo "ALLOCATE CHANNEL disk3 DEVICE TYPE DISK FORMAT '${asm_disk}';" >> ${RMAN_CMD_FILE} echo "ALLOCATE CHANNEL disk4 DEVICE TYPE DISK FORMAT '${asm_disk}';" >> ${RMAN_CMD_FILE} echo "CONFIGURE SNAPSHOT CONTROLFILE NAME TO '${ORACLE_HOME}/dbs/snapcf_${ORACLE_SID}.f';" >> ${RMAN_CMD_FILE} # echo "CONFIGURE DEVICE TYPE DISK BACKUP TYPE TO COMPRESSED BACKUPSET PARALLELISM 4;" >> ${RMAN_CMD_FILE} # echo "CONFIGURE DEVICE TYPE DISK BACKUP TYPE TO COMPRESSED BACKUPSET;" >> ${RMAN_CMD_FILE} echo "sql 'ALTER SYSTEM ARCHIVE LOG CURRENT';" >> ${RMAN_CMD_FILE} [ "${DEBUG}" == "Y" ] && echo "DEBUG: Backup Type is set to ${BACKUP_TYPE}." [ "${DEBUG}" == "Y" ] && echo "DEBUG: Level ZERO Backup Day is set to ${LEVEL_0_DAY}." case ${BACKUP_TYPE} in "INCR") echo "CROSSCHECK backup of database;" >> ${RMAN_CMD_FILE} echo "CROSSCHECK backup of controlfile;" >> ${RMAN_CMD_FILE} echo "CROSSCHECK backup of spfile;" >> ${RMAN_CMD_FILE} echo "CROSSCHECK backup of archivelog all;" >> ${RMAN_CMD_FILE} case `date +%a | tr "[a-z]" "[A-Z]"` in ${LEVEL_0_DAY}) [ "${DEBUG}" == "Y" ] && echo "DEBUG: Type: INCR Level 0" echo "BACKUP as compressed backupset SECTION SIZE 20G INCREMENTAL LEVEL 0 TAG='L0_${ORACLE_SID}_`date +%d%m%YT%H%M%S`' DATABASE include current CONTROLFILE plus ARCHIVELOG;" >> ${RMAN_CMD_FILE} ;; *) [ "${DEBUG}" == "Y" ] && echo "DEBUG: Type: INCR Level 1" echo "BACKUP as compressed backupset SECTION SIZE 20G INCREMENTAL LEVEL 1 TAG='L1_${ORACLE_SID}_`date +%d%m%YT%H%M%S`' DATABASE include current CONTROLFILE plus ARCHIVELOG;" >> ${RMAN_CMD_FILE} ;; esac;; "ARCH") [ "${DEBUG}" == "Y" ] && echo "DEBUG: Type: ARCH" echo "backup as compressed backupset TAG='Arch_${ORACLE_SID}_`date +%d%m%YT%H%M%S`' archivelog all;" >> ${RMAN_CMD_FILE} ;; esac # echo "delete noprompt archivelog all backed up 1 times to DEVICE TYPE disk completed before 'sysdate-1';" >> ${RMAN_CMD_FILE} # echo "delete noprompt archivelog all backed up 2 times to DEVICE TYPE disk completed before 'sysdate-1';" >> ${RMAN_CMD_FILE} # echo "delete noprompt archivelog all backed up 1 times to DEVICE TYPE disk completed before 'sysdate-${RETENTION_DAYS}';" >> ${RMAN_CMD_FILE} # echo "delete noprompt expired backup;" >> ${RMAN_CMD_FILE} if is_fs_mounted then [ -d ${BACKUP_FS}/${ORACLE_SID} ] || mkdir ${BACKUP_FS}/${ORACLE_SID} /bin/find ${BACKUP_FS}/${ORACLE_SID} -type f -empty -delete echo "backup backupset all NOT BACKED UP 2 TIMES format '${BACKUP_FS}/${ORACLE_SID}/%U';" >> ${RMAN_CMD_FILE} else echo -e "WARNING: Backup filesystem not mounted....." fi echo "DELETE FORCE NOPROMPT OBSOLETE;" >> ${RMAN_CMD_FILE} echo "}" >> ${RMAN_CMD_FILE} echo "exit" >> ${RMAN_CMD_FILE} } # ===================================================================================================================================================================== export DEBUG="N" # "Y"||"N" export ORACLE_SID=`echo ${1} | tr "[a-z]" "[A-Z]"` export RETENTION_DAYS=${2} export BACKUP_TYPE=`echo ${3} | tr "[a-z]" "[A-Z]"` export LEVEL_0_DAY=`echo ${4:-ZZZ} | tr "[a-z]" "[A-Z]"` test `uname -n` = "uks-odbnrgtst-02" && export ORACLE_HOME="/u01/app/oracle/product/11.2.0/dbhome_1" || export ORACLE_HOME="/u01/app/oracle/product/11.2.0/db_1" export SCRIPT_DIR="/home/oracle/Scripts/RMAN" [ "${DEBUG}" == "Y" ] && echo -e "DEBUG: Debugging is switched on." [ "${DEBUG}" == "Y" ] && export RMAN_CMD_FILE=${SCRIPT_DIR}/${ORACLE_SID}_rman_cmds_DEBUG.rman || export RMAN_CMD_FILE=${SCRIPT_DIR}/${ORACLE_SID}_rman_cmds.rman export BACKUP_FS="/backups" export BACKUP_LOG=${SCRIPT_DIR}/logs/${ORACLE_SID}_${BACKUP_TYPE}_backup_log.log [ -d ${SCRIPT_DIR}/logs ] || mkdir ${SCRIPT_DIR}/logs if [ ${#} -le 4 ] then echo `date` >> ${BACKUP_LOG} if is_not_guarded # 0;SI/SBY then if is_RMAN_running then ORACLE_SID=`echo ${ORACLE_SID} | tr "[a-z]" "[A-Z]"` if is_sid_valid then if [[ "${2}" = +([0-9]) ]] then if [[ "${BACKUP_TYPE}" == "ARCH" || "${BACKUP_TYPE}" == "INCR" ]] then if is_day_valid then build_cmdfile [ "${DEBUG}" == "Y" ] && echo ${ORACLE_HOME}/bin/rman cmdfile=${RMAN_CMD_FILE} log=${SCRIPT_DIR}/logs/${ORACLE_SID}_RMAN_${BACKUP_TYPE}_backup.log || ${ORACLE_HOME}/bin/rman cmdfile=${RMAN_CMD_FILE} log=${SCRIPT_DIR}/logs/${ORACLE_SID}_RMAN_${BACKUP_TYPE}_backup.log if [ $? = 0 ] then echo -e "\nINFO: ${ORACLE_SID} Database Backup Successful." >> ${BACKUP_LOG} else echo -e "\nERROR: ${ORACLE_SID} Database Backup Failed." >> ${BACKUP_LOG} fi else echo -e "\nERROR: Parameter 4: Invalid Level-0 Backup Day entered .\n" fi else echo -e "\nERROR: Parameter 3: Backup Type must be or .\n" fi else echo -e "\nERROR: Parameter 2: Retention Days must be numeric, in days.\n" fi else echo -e "\nERROR: Parameter 1: Database '${ORACLE_SID}' does not exist.\n" fi else echo -e "\nINFO: RMAN is already running.\n" fi fi else echo -e "\nUsage: RMAN_DB_backup.ksh \n" fi # End of File