RMAN_DB_Backup_v103.ksh 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. #!/bin/ksh
  2. # set -x
  3. # ======================================================================================================================================
  4. # Title: RMAN_DB_Backup.ksh
  5. # Author: Richard Wilson
  6. # Date: 03.04.2014
  7. # File Name: RMAN_DB_Backup_v???.ksh
  8. # Description: Uses RMAN to backup Oracle databases.
  9. # Usage: RMAN_DB_backup_v???.ksh <ORACLE_SID> <RETENTION_PERIOD> <ARCH|INCR> <LEVEL_0_DAY> <CAT|NOCAT>
  10. # --------------------------------------------------------------------------------------------------------------------------------------
  11. # History:
  12. # 17.04.2014 RW Added %d%m%Y to Tag.
  13. # 24.07.2014 RW Added email notification.
  14. # 29.07.2014 RW Added more logic - email after 'backup backup'.
  15. # 26.09.2014 RW Included parameter Retention Period.
  16. # 03.12.2014 RW Changed to use R5DISK for UAT, SIT & TRAIN.
  17. # 11.05.2015 RW Removed Full backups, added Incremental backups.
  18. # 09.02.2016 RW Added function 'is_RMAN_running'.
  19. # 09.02.2016 RW Added backup 'NOT BACKED UP 2 TIMES' to capture any missed backupsets.
  20. # 25.04.2017 RW Added 'Day' input parameter and 'is_day_valid' function.
  21. # 10.05.2017 RW Added Level-0 Backup Day input parameter.
  22. # 10.05.2017 RW Moved CROSSCHECKS into Level-0 only.
  23. # 12.12.2017 RW Added 'is_not_guarded' function to allow backup on STANDBY.
  24. # 21.12.2017 RW Added dbhome_1/db_1 logic for ORACLE_HOME.
  25. # 11.04.2018 RW Added Data Guard function is_not_guarded.
  26. # 16.05.2018 RW Added get_db_role and get_DB_type procedures.
  27. # 17.05.2018 RW Modifications for RMAN-05021: this configuration cannot be changed for a BACKUP or STANDBY control file.
  28. # 18.05.2018 RW Modified for Single Instance, Primary, and Standby backups.
  29. # ---------------------------------------------------------------------------------------------------------------------------------------
  30. function is_fs_mounted
  31. {
  32. mount | grep "${BACKUP_FS}" > /dev/null && return 0 || return 1
  33. }
  34. function is_sid_valid
  35. {
  36. if [ `ps -ef | grep -v grep | grep -w "ora_pmon_${ORACLE_SID}$" | wc -l 2> /dev/null` -eq 0 ]
  37. then
  38. return 1
  39. else
  40. return 0
  41. fi
  42. }
  43. function is_day_valid
  44. {
  45. case "${LEVEL_0_DAY}" in
  46. MON|TUE|WED|THU|FRI|SAT|SUN|ZZZ)
  47. return 0;;
  48. *) return 1;;
  49. esac
  50. }
  51. function is_RMAN_running
  52. {
  53. return `${ORACLE_HOME}/bin/sqlplus -S / "as sysdba" <<-EOF
  54. set pagesize 0 feedback off verify off heading off termout off echo off
  55. select count(1) from sys.v\\$RMAN_STATUS where status like 'RUNNING%';
  56. EOF`
  57. }
  58. function is_not_guarded
  59. {
  60. return `${ORACLE_HOME}/bin/sqlplus -S / "as sysdba" <<-EOF
  61. set pagesize 0 feedback off verify off heading off termout off echo off
  62. select count(1) from sys.v\\$archive_dest where status = 'VALID' and target = 'STANDBY';
  63. EOF`
  64. }
  65. get_db_role()
  66. {
  67. db_role=`${ORACLE_HOME}/bin/sqlplus -S / "as sysdba" <<-EOF
  68. set pagesize 0 feedback off verify off heading off termout off echo off
  69. select database_role from v\\$DATABASE;
  70. EOF`
  71. }
  72. get_DB_type()
  73. {
  74. get_db_role
  75. if is_not_guarded
  76. then
  77. if [ "${db_role}" = "PHYSICAL STANDBY" ]; then
  78. [ "${DEBUG}" == "Y" ] && echo "${db_role}: Physical Standby"
  79. export DB_TYPE=3
  80. else
  81. [ "${DEBUG}" == "Y" ] && echo "${db_role}: Single Instance."
  82. export DB_TYPE=1
  83. fi
  84. else
  85. [ "${DEBUG}" == "Y" ] && echo "${db_role}: Primary (Dataguarded)."
  86. export DB_TYPE=2
  87. fi
  88. }
  89. set_cat()
  90. {
  91. case ${#} in
  92. 4) if [ "${3}" = "ARCH" ]
  93. then
  94. export USE_CAT=`echo ${4} | tr "[a-z]" "[A-Z]"`
  95. fi;;
  96. 5) if [ "${3}" = "INCR" ]
  97. then
  98. export USE_CAT=`echo ${5} | tr "[a-z]" "[A-Z]"`
  99. fi;;
  100. *) export USE_CAT="NOCAT";;
  101. esac
  102. }
  103. set_asm_dest()
  104. {
  105. case "${ORACLE_SID}" in
  106. SIT2|DMSIT|IFCE|SYSTST|SYSTST2|GOLD|GOLD2|PACK|PACK2|UPK) asm_disk="+R5DISK";;
  107. *) asm_disk="+FRA";;
  108. esac
  109. }
  110. build_cmdfile()
  111. {
  112. echo "connect target sys/newr00t@${ORACLE_SID}" > ${RMAN_CMD_FILE}
  113. [ "${DEBUG}" == "Y" ] && echo "DEBUG: Catalog is ${USE_CATALOG}."
  114. if [[ "${USE_CATALOG}" == "CAT" ]]; then
  115. echo "connect catalog rcatadm/RCATADM@RCAT" >> ${RMAN_CMD_FILE}
  116. fi
  117. echo "run {" >> ${RMAN_CMD_FILE}
  118. echo "sql 'alter session set optimizer_mode=RULE';" >> ${RMAN_CMD_FILE}
  119. echo "sql 'ALTER SYSTEM SET CONTROL_FILE_RECORD_KEEP_TIME=60 SCOPE=BOTH';" >> ${RMAN_CMD_FILE}
  120. if [[ ${DB_TYPE} = 1 || ${DB_TYPE} = 2 ]]
  121. then
  122. echo "CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF ${RETENTION_DAYS} DAYS;" >> ${RMAN_CMD_FILE}
  123. echo "sql 'ALTER SYSTEM ARCHIVE LOG CURRENT';" >> ${RMAN_CMD_FILE}
  124. fi
  125. echo "CONFIGURE CONTROLFILE AUTOBACKUP ON;" >> ${RMAN_CMD_FILE}
  126. echo "CONFIGURE SNAPSHOT CONTROLFILE NAME TO '${ORACLE_HOME}/dbs/snapcf_${ORACLE_SID}.f';" >> ${RMAN_CMD_FILE}
  127. if [[ ${DB_TYPE} = 1 || ${DB_TYPE} = 3 ]]
  128. then
  129. set_asm_dest
  130. echo "ALLOCATE CHANNEL disk1 DEVICE TYPE DISK FORMAT '${asm_disk}';" >> ${RMAN_CMD_FILE}
  131. echo "ALLOCATE CHANNEL disk2 DEVICE TYPE DISK FORMAT '${asm_disk}';" >> ${RMAN_CMD_FILE}
  132. echo "ALLOCATE CHANNEL disk3 DEVICE TYPE DISK FORMAT '${asm_disk}';" >> ${RMAN_CMD_FILE}
  133. echo "ALLOCATE CHANNEL disk4 DEVICE TYPE DISK FORMAT '${asm_disk}';" >> ${RMAN_CMD_FILE}
  134. fi
  135. if [[ ${DB_TYPE} = 2 || ${DB_TYPE} = 3 ]]
  136. then
  137. echo "CONFIGURE ARCHIVELOG DELETION POLICY TO BACKED UP 2 TIMES TO DISK APPLIED ON ALL STANDBY;" >> ${RMAN_CMD_FILE}
  138. else
  139. # echo "CONFIGURE ARCHIVELOG DELETION POLICY TO BACKED UP 2 TIMES TO DISK COMPLETED BEFORE 'SYSDATE-${RETENTION_DAYS}';" >> ${RMAN_CMD_FILE}
  140. echo "CONFIGURE ARCHIVELOG DELETION POLICY TO BACKED UP 2 TIMES TO DISK;" >> ${RMAN_CMD_FILE}
  141. fi
  142. [ "${DEBUG}" == "Y" ] && echo "DEBUG: Backup Type is set to ${BACKUP_TYPE} - (L0 Backups on ${LEVEL_0_DAY})."
  143. if [[ ${DB_TYPE} = 1 || ${DB_TYPE} = 3 ]]
  144. then
  145. case ${BACKUP_TYPE} in
  146. "INCR")
  147. echo "CROSSCHECK backup;" >> ${RMAN_CMD_FILE}
  148. case `date +%a | tr "[a-z]" "[A-Z]"` in
  149. ${LEVEL_0_DAY}) [ "${DEBUG}" == "Y" ] && echo "DEBUG: Type: INCR Level 0"
  150. 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}
  151. ;;
  152. *) [ "${DEBUG}" == "Y" ] && echo "DEBUG: Type: INCR Level 1"
  153. 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}
  154. ;;
  155. esac;;
  156. "ARCH") [ "${DEBUG}" == "Y" ] && echo "DEBUG: Type: ARCH"
  157. echo "backup as compressed backupset TAG='Arch_${ORACLE_SID}_`date +%d%m%YT%H%M%S`' archivelog all;" >> ${RMAN_CMD_FILE}
  158. ;;
  159. esac
  160. if is_fs_mounted
  161. then
  162. [ -d ${BACKUP_FS}/${ORACLE_SID} ] || mkdir ${BACKUP_FS}/${ORACLE_SID}
  163. [ "${DEBUG}" == "Y" ] && echo "/bin/find ${BACKUP_FS}/${ORACLE_SID} -type f -empty -delete" || /bin/find ${BACKUP_FS}/${ORACLE_SID} -type f -empty -delete
  164. echo "BACKUP BACKUPSET all NOT BACKED UP 2 TIMES format '${BACKUP_FS}/${ORACLE_SID}/%U';" >> ${RMAN_CMD_FILE}
  165. else
  166. echo -e "WARNING: Backup filesystem not mounted....."
  167. fi
  168. fi
  169. echo "DELETE NOPROMPT OBSOLETE;" >> ${RMAN_CMD_FILE}
  170. echo "DELETE NOPROMPT EXPIRED BACKUP;" >> ${RMAN_CMD_FILE}
  171. echo "}" >> ${RMAN_CMD_FILE}
  172. echo "exit" >> ${RMAN_CMD_FILE}
  173. }
  174. # Main ==================================================================================================================================================================
  175. export DEBUG="Y" # "Y"||"N"
  176. export ORACLE_SID=`echo ${1} | tr "[a-z]" "[A-Z]"`
  177. export RETENTION_DAYS=${2}
  178. export BACKUP_TYPE=`echo ${3} | tr "[a-z]" "[A-Z]"`
  179. export LEVEL_0_DAY=`echo ${4:-ZZZ} | tr "[a-z]" "[A-Z]"`
  180. export SCRIPT_DIR="/home/oracle/Scripts/RMAN"
  181. export BACKUP_FS="/backups"
  182. export BACKUP_LOG=${SCRIPT_DIR}/logs/${ORACLE_SID}_${BACKUP_TYPE}_backup_log.log
  183. test `echo ${5:-NOCAT} | tr "[a-z]" "[A-Z]"` = "CAT" && USE_CATALOG="CAT" || USE_CATALOG="NOCAT"
  184. 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"
  185. [ "${DEBUG}" == "Y" ] && echo "-- Debug Output ----------------------------------------------------------------------------------------------------"
  186. [ "${DEBUG}" == "Y" ] && echo "DEBUG: Debugging is switched on."
  187. [ "${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
  188. [ -d ${SCRIPT_DIR}/logs ] || mkdir ${SCRIPT_DIR}/logs
  189. if [ ${#} -eq 4 -o ${#} -eq 5 ]
  190. then
  191. echo `date` >> ${BACKUP_LOG}
  192. if is_RMAN_running
  193. then
  194. ORACLE_SID=`echo ${ORACLE_SID} | tr "[a-z]" "[A-Z]"` # 1
  195. if is_sid_valid
  196. then
  197. if [[ "${2}" = +([0-9]) ]] # 2
  198. then
  199. if [[ "${BACKUP_TYPE}" == "ARCH" || "${BACKUP_TYPE}" == "INCR" ]] # 3
  200. then
  201. if is_day_valid
  202. then
  203. get_DB_type
  204. set_cat
  205. build_cmdfile
  206. [ "${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
  207. if [ $? = 0 ]
  208. then
  209. echo -e "\nINFO: ${ORACLE_SID} Database Backup Successful." >> ${BACKUP_LOG}
  210. else
  211. echo -e "\nERROR: ${ORACLE_SID} Database Backup Failed." >> ${BACKUP_LOG}
  212. fi
  213. else
  214. echo -e "\nERROR: Parameter 4: Invalid Level-0 Backup Day entered <Mon|Tue|Wed|Thu|Fri|Sat|Sun>.\n"
  215. fi
  216. else
  217. echo -e "\nERROR: Parameter 3: Backup Type must be <INCR> or <ARCH>.\n"
  218. fi
  219. else
  220. echo -e "\nERROR: Parameter 2: Retention Days must be numeric, in days.\n"
  221. fi
  222. else
  223. echo -e "\nERROR: Parameter 1: Database '${ORACLE_SID}' does not exist.\n"
  224. fi
  225. else
  226. echo -e "\nINFO: RMAN is already running.\n"
  227. fi
  228. else
  229. echo -e "\nUsage: RMAN_DB_backup.ksh <ORACLE_SID> <RETENTION_DAYS> <ARCH|INCR> <FULL_BACKUP_DAY> <CATALOG|NOCATALOG>\n"
  230. fi
  231. [ "${DEBUG}" == "Y" ] && (echo "-- RMAN cmd File ----------------------------------------------------------------------------------------------------"; cat ${RMAN_CMD_FILE})
  232. # ================== End of File =============================================================================================================================================