Last active
March 29, 2022 09:18
-
-
Save haballan/86a59a3b6d8d470926024710e5b330a4 to your computer and use it in GitHub Desktop.
Script to be used on the crontab to schedule an RMAN Full Backup (Variables in the first section must be modified before using the script)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ############################################################################################## | |
# Script to be used on the crontab to schedule an RMAN Full Backup | |
VER="[1.3]" | |
# ############################################################################################## | |
# # # # | |
# Author: Mahmmoud ADEL # # # # ### | |
# Created: 04-10-17 # # # # # | |
# | |
# Modified: | |
# 10-03-19 Add the option of deleting old CONTROLFILE AUTOBACKUP files. | |
# 16-06-20 Add Backup tag option. | |
# 16-06-20 Add the option of deleting the last backup taken by the same script. | |
# 16-06-20 Add the check of ORACLE HOME validity. | |
# ############################################################################################## | |
# ############################################################## | |
# VARIABLES To be Modified by the user to match the Environment: | |
# ############################################################## | |
# INSTANCE Name: [Replace ${ORACLE_SID} with your instance SID] | |
ORACLE_SID=${ORACLE_SID} | |
# ORACLE_HOME Location: [Replace ${ORACLE_HOME} with the right ORACLE_HOME path] | |
ORACLE_HOME=${ORACLE_HOME} | |
# Backup Name: [TAG] [Replace DAILYBKP with the backup name you want to tag] | |
BACKUPTAG=DAILYBKP | |
# Backup Location: [Replace /backup/rmanfull with the backup location path] | |
BACKUPLOC=/backup/rmanfull | |
# Backup LOG location: | |
RMANLOG=${BACKUPLOC}/rmanfull.log | |
# COMPRESSED BACKUP option:[Y|N] [Default Y] | |
COMPRESSION=Y | |
# Perform Maintenance based on below Backup & Archivelog Retention: [Y|N] [Default DISABLED] | |
MAINTENANCEFLAG=N | |
# Delete the last backup taken by the same script: [Y|N] [Default Y] | |
DELETE_LAST_BKP=Y | |
# Backup Retention "In Days": [Backups older than this retention will be deleted] | |
BKP_RETENTION=7 | |
# Archives Deletion "In Days": [Archivelogs older than this retention will be deleted] | |
ARCH_RETENTION=7 | |
# CONTROLFILE AUTOBACKUP Retention "In Days": [AUTOBACKUP of CONTROLFILE older than this retention will be deleted] | |
CTRL_AUTOBKP_RETENTION=7 | |
# ################## | |
# GENERIC VARIABLES: [Can be left without modification] | |
# ################## | |
# MAX BACKUP Piece Size: [To be considered, it should be BIGGER than the size of the biggest datafile in the database] | |
MAX_BKP_PIECE_SIZE=33g | |
# Show the full DATE and TIME details in the backup log: | |
NLS_DATE_FORMAT='DD-MON-YYYY HH24:MI:SS' | |
export ORACLE_SID | |
export ORACLE_HOME | |
export BACKUPTAG | |
export BACKUPLOC | |
export COMPRESSION | |
export BKP_RETENTION | |
export ARCH_RETENTION | |
export MAX_BKP_PIECE_SIZE | |
export RMANLOG | |
export NLS_DATE_FORMAT | |
export MAINTENANCEFLAG | |
# Check if the backup location is writable: | |
if [ ! -w ${BACKUPLOC} ]; then | |
echo | |
echo -e "\033[32;5mERROR: THE PROVIDED BACKUP LOCATION [${BACKUPLOC}] IS NOT WRITABLE !\033[0m" | |
echo | |
echo "Please provide a valid backup location by editing the value of variable 'BACKUPLOC' inside the script." | |
echo | |
exit | |
fi | |
# Check the selected COMPRESSION option: | |
case ${COMPRESSION} in | |
Y|y|YES|Yes|yes|ON|on) | |
COMPRESSED_BKP="AS COMPRESSED BACKUPSET" | |
export COMPRESSED_BKP | |
;; | |
*) | |
COMPRESSED_BKP="" | |
export COMPRESSED_BKP | |
;; | |
esac | |
# Check DELETE LAST BACKUP option: | |
case ${DELETE_LAST_BKP} in | |
Y|y|YES|Yes|yes|ON|on) | |
HASH_DELETE_LAST_BKP="" | |
export HASH_DELETE_LAST_BKP | |
;; | |
*) | |
HASH_DELETE_LAST_BKP="#" | |
export HASH_DELETE_LAST_BKP | |
;; | |
esac | |
# Check the selected MAINTENANCE option: | |
case ${MAINTENANCEFLAG} in | |
Y|y|YES|Yes|yes|ON|on) | |
HASH_MAINT="" | |
export HASH_MAINT | |
;; | |
*) | |
HASH_MAINT="#" | |
export HASH_MAINT | |
;; | |
esac | |
# Check if ORACLE_SID was missed by the user: | |
# ########################################## | |
if [ -z ${ORACLE_SID} ]; then | |
echo "ORACLE_SID was missed, the script will set it to the only running instance if found ..." | |
# Count Instance Numbers: | |
INS_COUNT=$( ps -ef|grep pmon|grep -v grep|egrep -v ${EXL_DB}|wc -l ) | |
# Exit if No DBs are running: | |
if [ $INS_COUNT -eq 0 ] | |
then | |
echo No Database is Running ! | |
exit | |
fi | |
# If there is ONLY one DB set it as default without prompt for selection: | |
if [ $INS_COUNT -eq 1 ] | |
then | |
export ORACLE_SID=$( ps -ef|grep pmon|grep -v grep|egrep -v ${EXL_DB}|awk '{print $NF}'|sed -e 's/ora_pmon_//g'|grep -v sed|grep -v "s///g" ) | |
echo "Script found only 1 running instance." | |
echo "Script will run against [${ORACLE_SID}] DB ..." | |
else | |
echo "Script is unable to identify which instance to run against!" | |
echo "Please provide a value for ORACLE_SID inside the script." | |
echo "Script Terminated!" | |
exit | |
fi | |
fi | |
# Check if the given ORACLE_HOME is valid: | |
# ####################################### | |
if [ ! -d ${ORACLE_HOME} ]; then | |
echo "ORACLE HOME is not valid, the script will search for the right ORACLE HOME ..." | |
ORA_USER=`ps -ef|grep ${ORACLE_SID}|grep pmon|grep -v grep|egrep -v ${EXL_DB}|awk '{print $1}'|tail -1` | |
USR_ORA_HOME=`grep ${ORA_USER} /etc/passwd| cut -f6 -d ':'|tail -1` | |
# SETTING ORATAB: | |
if [ -f /etc/oratab ] | |
then | |
ORATAB=/etc/oratab | |
export ORATAB | |
## If OS is Solaris: | |
elif [ -f /var/opt/oracle/oratab ] | |
then | |
ORATAB=/var/opt/oracle/oratab | |
export ORATAB | |
fi | |
# ATTEMPT1: Get ORACLE_HOME using pwdx command: | |
PMON_PID=`pgrep -lf _pmon_${ORACLE_SID}|awk '{print $1}'` | |
export PMON_PID | |
ORACLE_HOME=`pwdx ${PMON_PID}|awk '{print $NF}'|sed -e 's/\/dbs//g'` | |
export ORACLE_HOME | |
# ATTEMPT2: If ORACLE_HOME not found get it from oratab file: | |
if [ ! -f ${ORACLE_HOME}/bin/sqlplus ] | |
then | |
## If OS is Linux: | |
if [ -f /etc/oratab ] | |
then | |
ORATAB=/etc/oratab | |
ORACLE_HOME=`grep -v '^\#' ${ORATAB} | grep -v '^$'| grep -i "^${ORACLE_SID}:" | perl -lpe'$_ = reverse' | cut -f3 | perl -lpe'$_ = reverse' |cut -f2 -d':'` | |
export ORACLE_HOME | |
## If OS is Solaris: | |
elif [ -f /var/opt/oracle/oratab ] | |
then | |
ORATAB=/var/opt/oracle/oratab | |
ORACLE_HOME=`grep -v '^\#' ${ORATAB} | grep -v '^$'| grep -i "^${ORACLE_SID}:" | perl -lpe'$_ = reverse' | cut -f3 | perl -lpe'$_ = reverse' |cut -f2 -d':'` | |
export ORACLE_HOME | |
fi | |
fi | |
# ATTEMPT3: If ORACLE_HOME is in /etc/oratab, use dbhome command: | |
if [ ! -f ${ORACLE_HOME}/bin/sqlplus ] | |
then | |
ORACLE_HOME=`dbhome "${ORACLE_SID}"` | |
export ORACLE_HOME | |
fi | |
# ATTEMPT4: If ORACLE_HOME is still not found, search for the environment variable: [Less accurate] | |
if [ ! -f ${ORACLE_HOME}/bin/sqlplus ] | |
then | |
ORACLE_HOME=`env|grep -i ORACLE_HOME|sed -e 's/ORACLE_HOME=//g'` | |
export ORACLE_HOME | |
fi | |
# ATTEMPT5: If ORACLE_HOME is not found in the environment search user's profile: [Less accurate] | |
if [ ! -f ${ORACLE_HOME}/bin/sqlplus ] | |
then | |
ORACLE_HOME=`grep -h 'ORACLE_HOME=\/' ${USR_ORA_HOME}/.bash_profile ${USR_ORA_HOME}/.*profile | perl -lpe'$_ = reverse' |cut -f1 -d'=' | perl -lpe'$_ = reverse'|tail -1` | |
export ORACLE_HOME | |
fi | |
# ATTEMPT6: If ORACLE_HOME is still not found, search for orapipe: [Least accurate] | |
if [ ! -f ${ORACLE_HOME}/bin/sqlplus ] | |
then | |
if [ -x /usr/bin/locate ] | |
then | |
ORACLE_HOME=`locate -i orapipe|head -1|sed -e 's/\/bin\/orapipe//g'` | |
export ORACLE_HOME | |
fi | |
fi | |
fi | |
# Append the date to the backup log for each script execution: | |
echo "----------------------------" >> ${RMANLOG} | |
date >> ${RMANLOG} | |
echo "----------------------------" >> ${RMANLOG} | |
# ################### | |
# RMAN SCRIPT Section: | |
# ################### | |
${ORACLE_HOME}/bin/rman target / msglog=${RMANLOG} <<EOF | |
# Configuration Section: | |
# --------------------- | |
${HASH_MAINT}CONFIGURE BACKUP OPTIMIZATION ON; | |
${HASH_MAINT}CONFIGURE CONTROLFILE AUTOBACKUP ON; | |
${HASH_MAINT}CONFIGURE CONTROLFILE AUTOBACKUP FORMAT FOR DEVICE TYPE DISK TO '${BACKUPLOC}/%F'; | |
${HASH_MAINT}CONFIGURE SNAPSHOT CONTROLFILE NAME TO '${ORACLE_HOME}/dbs/snapcf_${ORACLE_SID}.f'; | |
## Avoid Deleting archivelogs NOT yet applied on the standby: [When FORCE is not used] | |
#CONFIGURE ARCHIVELOG DELETION POLICY TO APPLIED ON ALL STANDBY; | |
# Maintenance Section: | |
# ------------------- | |
## Crosscheck backups/copied to check for expired backups which are physically not available on the media: | |
${HASH_MAINT}crosscheck backup completed before 'sysdate-${BKP_RETENTION}' device type disk; | |
${HASH_MAINT}crosscheck copy completed before 'sysdate-${BKP_RETENTION}' device type disk; | |
## Report & Delete Obsolete backups which don't meet the RETENTION POLICY: | |
${HASH_MAINT}REPORT OBSOLETE RECOVERY WINDOW OF ${BKP_RETENTION} DAYS device type disk; | |
${HASH_MAINT}DELETE NOPROMPT OBSOLETE RECOVERY WINDOW OF ${BKP_RETENTION} DAYS device type disk; | |
## Delete All EXPIRED backups/copies which are not physically available: | |
${HASH_MAINT}DELETE NOPROMPT EXPIRED BACKUP COMPLETED BEFORE 'sysdate-${BKP_RETENTION}' device type disk; | |
${HASH_MAINT}DELETE NOPROMPT EXPIRED COPY COMPLETED BEFORE 'sysdate-${BKP_RETENTION}' device type disk; | |
## Crosscheck Archivelogs to avoid the backup failure: | |
${HASH_MAINT}CHANGE ARCHIVELOG ALL CROSSCHECK; | |
${HASH_MAINT}DELETE NOPROMPT EXPIRED ARCHIVELOG ALL; | |
## Delete Archivelogs older than ARCH_RETENTION days: | |
${HASH_MAINT}DELETE NOPROMPT archivelog all completed before 'sysdate -${ARCH_RETENTION}'; | |
## Delete AUTOBACKUP Controlfile older than CTRL_AUTOBKP_RETENTION days: | |
DELETE NOPROMPT BACKUP of controlfile completed before 'sysdate-${CTRL_AUTOBKP_RETENTION}'; | |
## Delete the LAST Full backup taken by the same script: | |
${HASH_DELETE_LAST_BKP}DELETE NOPROMPT BACKUP TAG='${BACKUPTAG}'; | |
# Full Backup Script starts here: [Compressed+Controlfile+Archives] | |
# ------------------------------ | |
run{ | |
allocate channel F1 type disk; | |
allocate channel F2 type disk; | |
allocate channel F3 type disk; | |
allocate channel F4 type disk; | |
sql 'alter system archive log current'; | |
BACKUP ${COMPRESSED_BKP} | |
#MAXSETSIZE ${MAX_BKP_PIECE_SIZE} | |
NOT BACKED UP SINCE TIME 'SYSDATE-2/24' | |
#INCREMENTAL LEVEL=0 | |
FORMAT '${BACKUPLOC}/%d_%t_%s_%p.bkp' | |
FILESPERSET 100 | |
TAG='${BACKUPTAG}' | |
DATABASE include current controlfile PLUS ARCHIVELOG NOT BACKED UP SINCE TIME 'SYSDATE-2/24'; | |
## Backup the controlfile separately: | |
BACKUP ${COMPRESSED_BKP} CURRENT CONTROLFILE FORMAT '${BACKUPLOC}/CONTROLFILE_%d_%I_%t_%s_%p.bkp' TAG='CONTROLFILE_BKP' REUSE ; | |
## Trace backup of Controlfile & SPFILE: | |
SQL "ALTER DATABASE BACKUP CONTROLFILE TO TRACE AS ''${BACKUPLOC}/controlfile.trc'' REUSE"; | |
SQL "CREATE PFILE=''${BACKUPLOC}/init${ORACLE_SID}.ora'' FROM SPFILE"; | |
} | |
EOF | |
# ############# | |
# END OF SCRIPT | |
# ############# | |
# REPORT BUGS to: mahmmoudadel@hotmail.com | |
# DOWNLOAD THE LATEST VERSION OF DATABASE ADMINISTRATION BUNDLE FROM: | |
# http://dba-tips.blogspot.com/2014/02/oracle-database-administration-scripts.html | |
# DISCLAIMER: THIS SCRIPT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY WARRANTY. IT IS PROVIDED "AS IS". |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment