Advertisement
Guest User

oracle-backup

a guest
Aug 8th, 2018
212
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.39 KB | None | 0 0
  1. [root@va01erp03 ~]# cat /u01/app/oracle/local/rman/bin/backup_database.sh
  2. #!/bin/sh
  3.  
  4. # 7/27/17 - BMB - Changing locking mechanism to allow the script to run multiple times and skip backups that are already running but allowing backups of other databsaes in the list if they aren't yet being backed up.
  5.  
  6. # Uncomment the following line to do a dry run
  7. #DEBUG=echo
  8.  
  9. PID=$$
  10.  
  11. # ALl lock files will be prefixed with this
  12. LOCKFILE_BASE=/tmp/backup-database.$PID
  13.  
  14.  
  15. # Must run as oracle user
  16. WHOAMI=`whoami`
  17. if [ "$WHOAMI" != "oracle" ]; then
  18. echo "Must run this script as oracle user"
  19. #exit
  20. fi
  21.  
  22. # S3 Stuff
  23. S3CMD=/usr/local/bin/aws
  24.  
  25. parse_url() {
  26. eval $(echo "$1" | sed -e "s#^\(\(.*\)://\)\?\(\([^:@]*\)\(:\(.*\)\)\?@\)\?\([^/?]*\)\(/\(.*\)\)\?#${PREFIX:-URL_}SCHEME='\2' \
  27. ${PREFIX:-URL_}USER='\4' ${PREFIX:-URL_}PASSWORD='\6' ${PREFIX:-URL_}HOST='\7' ${PREFIX:-URL_}PATH='\9'#")
  28. }
  29.  
  30. function usage {
  31. echo "Usage: $0 -t <full|archive|incremental-0|incremental-1> -s 'SIDS' [-e email] [-r /rsync/path] [-fo] [-prefix 'Some Prefix'] [-redundancy #]"
  32. echo "-t - one of the following:"
  33. echo " full - full backup"
  34. echo " archive - archive log backup"
  35. echo " incremental-0 - Level 0 incremental backup (full)"
  36. echo " incremental-1 - Level 1 incremental backup"
  37. echo "-s SID - required - list of SIDS, quoted and space delimited"
  38. echo "-e email - optional - comma delimited (no spaces) list of email addresses to send failure notification to"
  39. echo "-prefix <prefix> : Prefix to put in E-Mail subjects. Usually used by Penta to distinguish between different customers systems"
  40. echo "-r rsync-path - optional - path to rsync backup files to. Do not include the SID in the path"
  41. echo "-fo - optional - If set, only email failed backup notifications"
  42. echo "-redundancy <#> : The # of full backups to store. Defaults to 3."
  43. echo "-aws-access-key <key> : AWS Access Key"
  44. echo "-aws-secret-key <key> : AWS Secret Key"
  45. echo "-s3-url : S3 URL to sync files to"
  46. echo
  47. echo "Default lifecycle file in s3 directory can be overriden with a file called lifecycle-override.txt"
  48. echo "Example: $0 -t full -s 'PROD PROD_H' -e customer@domain.com -r /someshare"
  49. echo "Example: $0 -t archive -s 'PROD PROD_H' -e customer@domain.com"
  50. }
  51.  
  52. # make sure the lockfile is removed when we exit and then claim it
  53. trap "/bin/rm -f ${LOCKFILE_BASE}*; exit" INT TERM EXIT
  54.  
  55. function get_flash_recovery_area {
  56. echo "select name from V\$RECOVERY_FILE_DEST;" | sqlplus / as sysdba | grep \/
  57. }
  58.  
  59. function set_s3_bucket_lifecycle {
  60. FILE=$1
  61. $DEBUG aws s3api put-bucket-lifecycle --bucket $S3BUCKET --lifecycle-configuration $FILE --region $S3REGION
  62. }
  63.  
  64. function s3_sync {
  65. LOCALPATH=$1
  66. S3PATH=$2
  67. $DEBUG aws s3 sync $LOCALPATH ${S3PATH}/ --sse --storage-class STANDARD_IA --exclude "*.ctl" --quiet --region $S3REGION
  68. }
  69.  
  70.  
  71. function sync_files_to_s3 {
  72. LOCALPATH=$1
  73. S3PATH=$2
  74. RETCODE=0
  75. s3_sync $LOCALPATH $S3PATH
  76. if [ "$?" -ne 0 ]; then
  77. sleep 30
  78. s3_sync $LOCALPATH $S3PATH
  79. if [ "$?" -ne 0 ]; then
  80. sleep 30
  81. s3_sync $LOCALPATH $S3PATH
  82. if [ "$?" -ne 0 ]; then
  83. sleep 30
  84. s3_sync $LOCALPATH $S3PATH
  85. if [ "$?" -ne 0 ]; then
  86. sleep 30
  87. s3_sync $LOCALPATH $S3PATH
  88. else
  89. RETCODE=1
  90. fi
  91. fi
  92. fi
  93. fi
  94.  
  95. return $RETCODE
  96. }
  97.  
  98. if [ -z $1 ]; then
  99. usage
  100. exit
  101. fi
  102.  
  103. # Set the RMAN directory
  104. ORACLE_BASE=`cat ~/.oracle_base`
  105. RMAN_DIR=$ORACLE_BASE/local/rman
  106.  
  107. #Make sure /usr/local/bin is in the path and save it
  108. PATH=$PATH:/usr/local/bin
  109. ORIG_PATH=$PATH
  110.  
  111. # Defaults
  112. FAILURE_ONLY=0
  113. REDUNDANCY=3
  114.  
  115. while [ $# -gt 0 ]
  116. do
  117. case "$1" in
  118. -t) BACKUP_TYPE="$2"; shift;;
  119. -s) ORACLE_SIDS="$2"; shift;;
  120. -e) EMAIL="$2"; shift;;
  121. -prefix) EMAILPREFIX="$2"; shift;;
  122. -r) RSYNC_DEST="$2"; shift;;
  123. -s3-url) S3URL="$2"; shift;;
  124. -aws-access-key) export AWS_ACCESS_KEY_ID="$2"; shift;;
  125. -aws-secret-key) export AWS_SECRET_ACCESS_KEY="$2"; shift;;
  126. -fo) FAILURE_ONLY=1; shift;;
  127. -redundancy) REDUNDANCY="$2"; shift;;
  128. -*) usage; exit 1;;
  129. *) break;; # terminate while loop
  130. esac
  131. shift
  132. done
  133.  
  134. # extract bucket name from S3 URL
  135. if [ ! -z $S3URL ]; then
  136. parse_url $S3URL
  137. S3BUCKET=$URL_HOST
  138. S3REGION=$(aws s3api get-bucket-location --bucket $S3BUCKET --output text)
  139. # For some stupid reason get-bucket-location returns None if it's in the Standard region
  140. if [ "$S3REGION" == "None" ]; then
  141. S3REGION="us-east-1"
  142. fi
  143. fi
  144.  
  145. case $BACKUP_TYPE in
  146. "full")
  147. TYPE="Full Hot"
  148. RMAN_SCRIPT=$RMAN_DIR/bin/full_hot.rman
  149. SUBJECT="PENTA FULL DATABASE BACKUP"
  150. LOG_PREFIX="full_hot"
  151. ;;
  152. "archive")
  153. TYPE="Archive log"
  154. RMAN_SCRIPT=$RMAN_DIR/bin/archive.rman
  155. SUBJECT="PENTA DATABASE LOG BACKUP"
  156. LOG_PREFIX="archive"
  157. ;;
  158. "incremental-0")
  159. RMAN_SCRIPT=$RMAN_DIR/bin/incremental_level0.rman
  160. TYPE="Incremental Level 0"
  161. SUBJECT="PENTA INCREMENTAL FULL DATABASE BACKUP"
  162. LOG_PREFIX="incremental_0"
  163. ;;
  164. "incremental-1")
  165. RMAN_SCRIPT=$RMAN_DIR/bin/incremental_level1.rman
  166. TYPE="Incremental Level 1"
  167. SUBJECT="PENTA INCREMENTAL DATABASE BACKUP"
  168. LOG_PREFIX="incremental_1"
  169. ;;
  170. *)
  171.  
  172. echo "Invalid backup type. Must be full or archive"
  173. exit 255;
  174. ;;
  175. esac
  176.  
  177. function rsync_ready {
  178. # Verify rsync stuf
  179. # RSYNC PROCESS
  180. RSYNC_READY=0
  181. if [ ! -z $RSYNC_DEST ]; then
  182. # We must want to rsync since we were given a directory.
  183. # 1. Make sure it's a remotely mounted filesystem by seeing if it's a local filesystem
  184. if [ -d "$RSYNC_DEST/$1" ]; then
  185. cd "$RSYNC_DEST/$1"
  186. touch .test
  187. if [ "$?" == "0" ]; then
  188. # Make sure this is a remote filesystem....
  189. for FS in $(mount | egrep -v "(ext3|ext4|proc|sysfs|devpts|tmpfs|rpc_pipefs|acfs)" | awk '{print $3}'); do
  190. FS_FOUND=$(echo $FS|grep -c $RSYNC_DEST)
  191.  
  192. if [ $FS_FOUND == "1" ]; then
  193. RSYNC_READY=1
  194. fi
  195. done
  196. if [ $RSYNC_READY == "0" ]; then
  197. echo "***** $RSYNC_DEST/$1 NOT MOUNTED. Please check the share configuration. Continuing with local backup only *****"
  198. fi
  199. else
  200. echo "***** Cannot write to $RSYNC_DEST/$1. Please check the share configuration. Continuing with local backup only *****"
  201. FAILED=1
  202. fi
  203. else
  204. echo "***** $RSYNC_DEST/$1 doesn't exist. If this is the first time backing up databases to this directory then manually create $RSYNC_DEST/PROD. Continuing with local backup only. ******" | ma
  205. il -s "$EMAILPREFIX CRITICAL FAILURE DURING $SUBJECT" $EMAIL
  206. FAILED=1
  207. fi
  208. fi
  209.  
  210. return $RSYNC_READY
  211. }
  212.  
  213. DAY=`date +%F-%T`
  214.  
  215.  
  216. function send_failure_email {
  217. if [ ! -z $EMAIL ]; then # we have an email address specified
  218. echo "Backup Script Interrupted" | mail -s "$EMAILPREFIX CRITICAL FAILURE DURING $SUBJECT" $EMAIL
  219. fi
  220. }
  221.  
  222. trap 'send_failure_email' SIGINT SIGTERM
  223.  
  224. SUMMARY_EMAIL=/tmp/$$.$LOG_PREFIX.Summary.$DAY.log
  225. EMAIL_BODY=$RMAN_DIR/log/$LOG_PREFIX.$DAY.log
  226. cat /dev/null > $EMAIL_BODY
  227.  
  228. GLOBAL_FAILED=0
  229. for ORACLE_SID in $ORACLE_SIDS
  230. do
  231. echo "===========================================================" >> $EMAIL_BODY
  232. echo "$TYPE backup of $ORACLE_SID started at `date`" >> $EMAIL_BODY
  233.  
  234. LOCKFILE="${LOCKFILE_BASE}-${ORACLE_SID}"
  235. LOCKFILE_COUNT=`ls /tmp/backup-database.*${ORACLE_SID} 2> /dev/null | wc -l`
  236. if [ ${LOCKFILE_COUNT} -gt 0 ]; then
  237. echo "Backup of $ORACLE_SID already running, skipping"
  238. continue
  239. fi
  240. echo "Creating Lock File $LOCKFILE"
  241. touch $LOCKFILE
  242.  
  243. LOG_FILE=$RMAN_DIR/log/$LOG_PREFIX.$ORACLE_SID.$DAY.log
  244. cat /dev/null > $LOG_FILE
  245.  
  246. export ORACLE_SID
  247. # Set the PATH back to the original
  248. PATH=$ORIG_PATH
  249. export ORAENV_ASK=NO
  250. . /usr/local/bin/oraenv >> /dev/null 2>&1
  251.  
  252.  
  253. FAILED=0
  254. # Make sure the database is running on this server
  255. RUNNING=`lsnrctl status | grep -c \"$ORACLE_SID\"`
  256. if [ "$RUNNING" == "0" ]; then
  257. echo "Cannot locate a running database called $ORACLE_SID" >> $EMAIL_BODY
  258. FAILED=1
  259. else
  260.  
  261. $DEBUG $ORACLE_HOME/bin/rman @$RMAN_SCRIPT $REDUNDANCY >> $LOG_FILE
  262. RETCODE=$?
  263. if [ "$RETCODE" -gt "0" ]; then
  264. FAILED=1
  265. echo "$TYPE backup of $ORACLE_SID FAILED at `date` with return code $RETCODE" >> $EMAIL_BODY
  266. echo "Error below:" >> $EMAIL_BODY
  267. echo >> $EMAIL_BODY
  268. tail -10 $LOG_FILE >> $EMAIL_BODY
  269. echo >> $EMAIL_BODY
  270. echo >> $EMAIL_BODY
  271. else
  272. echo "$TYPE backup of $ORACLE_SID SUCCEEDED at `date` with return code $RETCODE" >> $EMAIL_BODY
  273. fi
  274.  
  275. FRA=`get_flash_recovery_area`
  276.  
  277. # Copy Backups to Amazon S3
  278. if [ ! -z $S3URL ]; then
  279. echo "Starting S3 Sync" >> $LOG_FILE
  280. if [ ! -e $S3CMD ]; then
  281. echo "AWS CLI not installed. Please install" >> $EMAIL_BODY
  282. FAILED=1
  283. else
  284. # Set the lifecycle for the database
  285. if [ ! -e $RMAN_DIR/bin/s3/lifecycle.txt ]; then
  286. echo "S3 Lifecycle file not found" >> $EMAIL_BODY
  287. FAILED=1
  288.  
  289. SID_POLICY=`grep -c "<ID>$ORACLE_SID</ID>" $RMAN_DIR/bin/s3/lifecycle.txt`
  290. if [ "$SID_POLICY" -eq 0 ]; then
  291. echo "S3 Lifecycle for $ORACLE_SID not found in lifecycle.txt" >> $EMAIL_BODY
  292. FAILED=1
  293. fi
  294. else
  295. LIFECYCLEFILE=lifecycle.txt
  296. if [ -e $RMAN_DIR/bin/s3/lifecycle-override.txt ]; then
  297. LIFECYCLEFILE=lifecycle-override.txt
  298. fi
  299. set_s3_bucket_lifecycle file://$RMAN_DIR/bin/s3/$LIFECYCLEFILE $S3BUCKET
  300. #if [ "$?" -gt 0 ]; then FAILED=1; echo "Setting S3 Bucket Lifecycle Failed" >> $EMAIL_BODY"; fi
  301. sync_files_to_s3 $FRA/$ORACLE_SID/backupset $S3URL/$ORACLE_SID/backupset
  302. RETCODE=$?
  303. if [ "$RETCODE" -gt 0 ]; then
  304. FAILED=1
  305. echo "FAILED TO COPY BACKUPS to S3!" >> $EMAIL_BODY
  306. else
  307. echo "S3 copy of $ORACLE_SID backupset to $S3URL/$ORACLE_SID/backupset complete" >> $EMAIL_BODY
  308. fi
  309. sync_files_to_s3 $FRA/$ORACLE_SID/autobackup $S3URL/$ORACLE_SID/autobackup
  310. RETCODE=$?
  311. if [ "$RETCODE" -gt 0 ]; then
  312. FAILED=1
  313. echo "FAILED TO COPY BACKUPS to S3!" >> $EMAIL_BODY
  314. else
  315. echo "S3 copy of $ORACLE_SID autobackup to $S3URL/$ORACLE_SID/autobackup complete" >> $EMAIL_BODY
  316. fi
  317.  
  318. # Audit to make sure the files are really there.
  319.  
  320. S3_FILE_LIST=/tmp/S3_FILE_LIST_$ORACLE_SID
  321. aws s3 ls --region $S3REGION --recursive $S3URL/$ORACLE_SID/ > $S3_FILE_LIST
  322. RETCODE=$?
  323. if [ "$RETCODE" -gt 0 ]; then
  324. FAILED=1
  325. echo "FAILED TO GET S3 FILE LIST!" >> $EMAIL_BODY
  326. else
  327. # Check the files we have
  328. for file in $(find $FRA/$ORACLE_SID -name '*.bkp' > /dev/null 2>&1); do
  329. RMAN_FILE=$(basename $file)
  330. S3_FILE_EXISTS=$(grep -c $RMAN_FILE $S3_FILE_LIST)
  331. if [ "$S3_FILE_EXISTS" -ne 1 ]; then
  332. echo "$RMAN_FILE not backed up to S3" >> $EMAIL_BODY
  333. FAILED=1
  334. S3_SYNC_FAILED=1
  335. fi
  336. done
  337. if [ -z $S3_SYNC_FAILED ]; then
  338. echo "S3 file audit of $ORACLE_SID backups complete. All local files found in S3" >> $EMAIL_BODY
  339. fi
  340. fi
  341. fi
  342. fi
  343. fi
  344.  
  345.  
  346. # Copy Backups to $RSYNC_DEST with rsync
  347. rsync_ready $ORACLE_SID
  348. RSYNC_READY=$?
  349.  
  350. if [ "$RSYNC_READY" == 1 ]; then
  351. # don't use -t, as that isn't compatible with Windows shares.
  352. # use -c to compare by checksum since we can't keep timestamps in sync.
  353. $DEBUG rsync -av --delete $FRA/$ORACLE_SID/backupset $RSYNC_DEST/$ORACLE_SID/ >> $LOG_FILE
  354. if [ $? != "0" ]; then
  355. echo "Failed to copy backups to $RSYNC_DEST" >> $EMAIL_BODY
  356. FAILED=1
  357. else
  358. echo "Remote copy of $ORACLE_SID backupset backups from $FRA to $RSYNC_DEST/$ORACLE_SID SUCCEEDED" >> $EMAIL_BODY
  359. fi
  360. # don't use -t, as that isn't compatible with Windows shares.
  361. # use -c to compare by checksum since we can't keep timestamps in sync.
  362. $DEBUG rsync -av --delete $FRA/$ORACLE_SID/autobackup $RSYNC_DEST/$ORACLE_SID/ >> $LOG_FILE
  363. if [ $? != "0" ]; then
  364. echo "Failed to copy backups to $RSYNC_DEST" >> $EMAIL_BODY
  365. FAILED=1
  366. else
  367. echo "Remote copy of $ORACLE_SID autobackup backups from $FRA to $RSYNC_DEST/$ORACLE_SID SUCCEEDED" >> $EMAIL_BODY
  368. fi
  369. else
  370. echo "Skipping rsync due to error validating remote mount point" >> $EMAIL_BODY
  371. fi
  372. fi
  373. echo "See Log File For Details: $LOG_FILE" >> $EMAIL_BODY
  374. echo "===========================================================" >> $EMAIL_BODY
  375. /bin/rm -f ${LOCKFILE}
  376. done
  377.  
  378. if [ ! -z $EMAIL ]; then # we have an email address specified
  379. if [ "$FAILED" == "1" ]; then # We ran into issues
  380. cat $LOG_FILE >> $EMAIL_BODY
  381. cat $EMAIL_BODY | mail -s "$EMAILPREFIX $SUBJECT FAILED - $ORACLE_SID" $EMAIL
  382. fi
  383. cat $EMAIL_BODY >> $SUMMARY_EMAIL
  384. else # We don't have an email address. Let's print to stdout
  385. if [ "$FAILED" == "1" ]; then # We ran into issues
  386. cat $LOG_FILE >> $EMAIL_BODY
  387. cat $EMAIL_BODY
  388. else # We didn't have any issues
  389. cat $EMAIL_BODY
  390. fi
  391. fi
  392.  
  393. if [ "$FAILED" == "1" ]; then
  394. GLOBAL_FAILED=1
  395. fi
  396.  
  397.  
  398. # E-Mail Summary
  399. if [ ! -z $EMAIL ]; then # we have an email address specified
  400. if [ "$FAILURE_ONLY" == "0" ]; then # Email no matter what the result
  401. cat $SUMMARY_EMAIL | mail -s "$EMAILPREFIX $SUBJECT BACKUP SUMMARY" $EMAIL
  402. fi
  403. fi
  404.  
  405. if [ $GLOBAL_FAILED == "1" ]; then
  406. exit 255
  407. fi
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement