📄 oraback.sh
字号:
#!/bin/sh## Rcs_ID="$RCSfile: oraback.sh,v $"# Rcs_ID="$Revision: 1.49 $ $Date: 2000/12/14 09:29:02 $"## @(#)oraback.sh - (Hot backups for Oracle databases)# Copyright (C) 1996 Curtis Preston - curtis@backupcentral.com## This program is free software; you can redistribute it and/or modify it# under the terms of the GNU General Public License as published by the Free# Software Foundation; either version 2 of the License, or (at your option)# any later version.## This program is distributed in the hope that it will be useful, but WITHOUT# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for# more details.## For a copy of the license, write to the Free Software# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139## Acknowledgements to: Samuel_Binder@coretech-group.com# (For assistance with sql commands and early coding.)################################################################################Site-specific section (change as appopriate)DEBUG=N #Set this to "Y" turn on set -x for all functionsCOMPRESS=compress #Can be set to gzip if you have itZ='Z' #Compression suffix (e.g. Z for compress, gz for gzip)BINDIR=/usr/local/bin #Location of this and related programsORACLE=oracle #ID that script will run asDBAGROUP=dba #GROUP that should own backup directoryORATAB=/var/opt/oracle/oratab #Location of oracle's oratab#ORACLE_HOME is normally determined by oratab, but you can set it hereORACLE_HOME=`grep -v '^#' $ORATAB|awk -F':' '{print $2}' |tail -1`ORACONF=/usr/local/bin/oraback.conf #Oraback.sh config file locationTMP=/var/tmp #Where temporary and permanent logs are keptSUCCESSMAIL=Y #Set to N if you only want to be mailed on failurePERMLOG=/db/oracle/oraback.log #Full path of oraback.sh logPATH=$PATH:/usr/bin:/usr/sbin:/sbin:/usr/5bin:/bin:$BINDIRORIG_PATH=$PATH#If you've changed the default init.ora and config.ora locations,#change them here.Find_config_files() {PFILE=$ORACLE_HOME/dbs/init${ORACLE_SID}.oraIFILE=$ORACLE_HOME/dbs/config${ORACLE_SID}.oraTNSNAMES=$ORACLE_HOME/network/admin/tnsnames.ora#SQLNET=$ORACLE_HOME/network/admin/sqlnet.oraLISTENER=$ORACLE_HOME/network/admin/listener.oraALERT=$ORACLE_BASE/admin/${ORACLE_SID}/bdump/alert${ORACLE_SID}.log}Preshut() { #Run prior to shutting down instance[ "$DEBUG" = Y ] && set -x}Poststart() { #Run after starting up instance[ "$DEBUG" = Y ] && set -x}Preback() { #Run prior to backup[ "$DEBUG" = Y ] && set -x}Postback() { #Run after entire backup finishes[ "$DEBUG" = Y ] && set -x}export BINDIR ORATAB ORACONF TMP PATH ORIG_PATH##End site-specific configuration section#############################################################################[ "$DEBUG" = Y ] && set -xUsage() { [ "$DEBUG" = Y ] && set -x echo "Usage: $0 [at|\$ORACLE_SID(s)]" echo "(Must be run as one of the following users:" echo "${USERS}." exit 1}Log_error() { #Sends errors to various places [ "$DEBUG" = Y ] && set -x if [ "$1" -gt 0 ] ; then TIME="`date '+%b %e %T'` $HOST" MSG=" `basename $0` $ORACLE_SID: WARNING:" ERR=`echo $2|sed "s/^/$TIME $MSG /"` echo "$ERR" |$TLOG echo "$ERR" >>$TMP/$X.Mail [ "$1" = 99 ] && touch $TMP/$X.Fatal if [ "$3" = exit ] ; then Mail_dba exit 1 fi fi}Error_chk() { #Check sqldba output files for errors [ "$DEBUG" = Y ] && set -x ERROR=`egrep -i 'dba\-|ora\-|mgr\-|error' $1` [ -n "$ERROR" ] && Log_error 1 "$ERROR" [ ! -s $1 ] && Log_error 99 "Bus error on svrmgr"}Backup_offline() { #Backup instance offline [ "$DEBUG" = Y ] && set -x echo " Backing up $ORACLE_SID OFFLINE." |$TLOG BTYPE=cold ; export BTYPE Backup_instance}Backup_instance() { #Backup all tablespaces in an instance [ "$DEBUG" = Y ] && set -x awk -F':' '{print $1}' $CWD/$TBLSPACE_LIST | sort -u |\ while read TBS ; do export TBS if [ -n "$SIMULT" ] ; then #Do in background if doing simult. b/u Throttle #(if there's not too many already) Backup_one_tablespace & else Backup_one_tablespace fi done #Done with all tablespaces while [ -n "`ls $TMP/$X.$ORACLE_SID.*.* 2>/dev/null`" ] ; do sleep 10 #Wait for all TBS's to finish done}Backup_one_tablespace() { #Backup all files in one tbs [ "$DEBUG" = Y ] && set -x TBS_STAT=`grep "^$TBS:" $CWD/$TBLSPACE_LIST | awk -F':' '{print $4}'|head -1` #If hot b/up, put in b/u mode if [ $BTYPE = "hot" -a "$TBS_STAT" != "READONLY" ] ; then $SVRMGR<<EOF_BOT >$TMP/$X.$TBS.tablebu 2>&1connect internal;alter tablespace $TBS begin backup;exit;EOF_BOT Error_chk $TMP/$X.$TBS.tablebu #Another all new section to make sure that they go into backup mode #First, we'll get a list of all the filenumbers that are in this tbs FILELIST=`grep "^${TBS}:" $CWD/$TBLSPACE_LIST|awk -F: '{print $3}'` #Set this to a "bad" value BACKUPSTAT=1 while [ $BACKUPSTAT -eq 1 ] ; do #Reset it to a "good" value BACKUPSTAT=0 #Get the backup status of all the datafiles $SVRMGR<<EOF_BU >$TMP/$X.$TBS.backup 2>&1connect internal;select file#, status from v\$backup;EOF_BU #Now check the backup status of each file for FILENUM in $FILELIST ; do #The file should say "ACTIVE," not "NOT ACTIVE" if it's in b/u mode FILESTAT=`grep "^ *${FILENUM} *NOT ACTIVE" $TMP/$X.$TBS.backup` #If the result is non-null, then the file is NOT in backup mode #Set the "retry" flag and break out of this for loop. (No sense #in looking any further.) if [ -n "$FILESTAT" ] ; then BACKUPSTAT=1 break fi done done #If we've made it this far, all files should be in b/u mode echo " `date +'%H:%M:%S %d/%m/%y'` - Started Tablespace backup for $TBS" \ | $TLOG else echo " Tablespace $TBS is READ-ONLY. It will not be put in backup mode." \ | $TLOG fi grep "^$TBS:" $CWD/$TBLSPACE_LIST | awk -F':' '{print $2}' | \ while read FILE ; do DBF_BASENAME=`echo $FILE|sed 's-/-_-g'|sed 's/_//'` export DBF_BASENAME if [ -n "$SIMULT" ] ; then #More simult. copying export FILE Throttle #Limit no. of simult. copies Copy_one_database_file & else CT=`cat $TMP/$X.CT` echo `expr $CT + 1` > $TMP/$X.CT export FILE CT Copy_one_database_file #Done if foreground fi done #Done with all files in TBS #As long as there are $X.*.$TBS.* files, this tbs is not done while [ -n "`ls $TMP/$X.*.$TBS.files.* 2>/dev/null`" ] ; do sleep 10 #Wait for all files to copy done #If this was a hot backup, take out of backup mode if [ $BTYPE = "hot" -a "$TBS_STAT" != "READONLY" ] ; then $SVRMGR << EOF_TBS > $TMP/$X.$TBS.tablebu 2>&1connect internal;alter tablespace $TBS end backup;exit;EOF_TBS Error_chk $TMP/$X.$TBS.tablebu #Another all new section to make sure that they come out of backup mode #First, we'll get a list of all the filenumbers that are in this tbs FILELIST=`grep "^${TBS}:" $CWD/$TBLSPACE_LIST|awk -F: '{print $3}'` #Set this to a "bad" value BACKUPSTAT=1 while [ $BACKUPSTAT -eq 1 ] ; do #Reset it to a "good" value BACKUPSTAT=0 #Get the backup status of all the datafiles $SVRMGR<<EOF_BU >$TMP/$X.$TBS.backup 2>&1connect internal;select file#, status from v\$backup;EOF_BU #Now check the backup status of each file for FILENUM in $FILELIST ; do #The file should say "NOT ACTIVE," if it's out of b/u mode FILESTAT=`grep "^ *${FILENUM} *NOT ACTIVE" $TMP/$X.$TBS.backup` #If the result is null, then the file is still in backup mode #Set the "retry" flag and break out of this for loop. (No sense #in looking any further.) if [ -z "$FILESTAT" ] ; then BACKUPSTAT=1 break fi done done echo " `date +'%H:%M:%S %d/%m/%y'` - Finished Tablespace backup for $TBS"\ | $TLOGfi}Copy_one_database_file() { [ "$DEBUG" = Y ] && set -x #Create file that tells oraback.sh that a copy of this file is running touch $TMP/$X.$ORACLE_SID.$TBS.files.$DBF_BASENAME [ -n "$TAPE" ] && DEVICE=$TAPE || DEVICE=$CWD/$DBF_BASENAME NEW=`find $FILE -newer $CWD/$DBF_BASENAME.$Z -print 2>/dev/null` #If datafile newer than b/u,or if no b/u file,copy it if [ $? -gt 0 -o "$NEW" = "$FILE" ] ; then echo " `date +'%H:%M:%S %d/%m/%y'` - ${CT} Backing up $FILE." |$TLOG if [ "$COMP" = Y ] ; then if [ -n "$TAPE" ] ; then #If going to tape, use dd and compress it dd if=$FILE bs=64k 2>/dev/null| $COMPRESS -c >$DEVICE else #If going to disk, compress it to a .Z file dd if=$FILE bs=64k 2>/dev/null| $COMPRESS -c >$DEVICE.$Z fi else #If not compressing, just send it to the device dd if=$FILE of=$DEVICE bs=64k 2>/dev/null fi Log_error $? "Error Copying $FILE to $DEVICE" else echo " `date +'%H:%M:%S %d/%m/%y'` - $FILE has not changed." |$TLOG fi #Remove the file that tells it this datafile is still copying rm -f $TMP/$X.$ORACLE_SID.$TBS.files.$DBF_BASENAME}Switch_logfile_n_backup_controlfile() { [ "$DEBUG" = Y ] && set -x echo " -----------------------------------------------------" |$TLOG echo " Creating backup controlfile - $CWD/backup.controlfile" |$TLOG #Get tracefile destination dir DUMPDEST=`cat $CWD/dumpdest.list` #Create a file to be used to find the b/u cont. file to trace touch $DUMPDEST/tracefile.timefile.empty [ -f $CWD/backup.controlfile ] && rm -f $CWD/backup.controlfile $SVRMGR << EOF_CONTROL >$TMP/$X.control 2>&1connect internal;alter system checkpoint;alter system archive log current;alter database backup controlfile to '$CWD/backup.controlfile';alter database backup controlfile to trace;exit;EOF_CONTROL Error_chk $TMP/$X.control #Find most recent archive logs currently in arch_dest if [ -d $ARCH_LOG_DIR -a -f $ARCH_LOG_DIR/${ARCH_LOG_FILE}* ] ; then NEWER=`find $ARCH_LOG_DIR -type f -name "${ARCH_LOG_FILE}*" \ -newer $OLD -print` NEWER=`echo $NEWER` NEWEST=`ls -t $NEWER|head -1` OLD_SIZE=`du -s $NEWEST|awk '{print $1}'` ; SLEEP=Y else [ ! -d $ARCH_LOG_DIR ] \ && Log_error 1 "Log destination (${ARCH_LOG_DIR}) not found." [ ! -f $ARCH_LOG_DIR/${ARCH_LOG_FILE}* ] \ && Log_error 1 "NO archive logs found in $ARCH_LOG_DIR." fi}Copy_control_and_essential_redolog_files() { [ "$DEBUG" = Y ] && set -x#This part is essentially worthless, as far as most dbas are concerned,#but is provided by request of some oraback.sh users.#(I think it helps in a cold backup, anyway...) if [ -f $CWD/$CONTROLFILE_LIST ] ; then echo " Manually copying controlfiles: " | $TLOG cat $CWD/$CONTROLFILE_LIST |sed 's/^/ /' | sed 's/ *$//' | $TLOG for CONTROLFILE in `grep -v '^$' $CWD/$CONTROLFILE_LIST` do CONTROLFILE_BASENAME=`echo $CONTROLFILE|sed 's-/-_-g'|sed 's/_//'` $COMPRESS -c $CONTROLFILE > $CWD/$CONTROLFILE_BASENAME.$Z Log_error $? "Error copying $FILE to $CWD" done else Log_error 1 "$CWD/$CONTROLFILE_LIST: File not found" fi if [ -f $CWD/$LOGFILE_LIST ] ; then if [ -z "$NOLOG" ] ; then #If Instance is up, remove old logs in b/u dir, otherwise leave them if [ "$DB_UP" = 2 ] ; then REMOVE=`ls $CWD/backup.${ARCH_LOG_FILE}* 2>/dev/null|grep -v "$BOLD"` if [ -n "$REMOVE" ] ; then echo " Removing old archive logs: " |$TLOG ls $CWD/backup.${ARCH_LOG_FILE}* 2>/dev/null|grep -v "$BOLD" \ |sed 's/^/ /' | $TLOG rm -f $REMOVE else echo " NO old archive logs found." |$TLOG fi fi echo " Copying archived redo logs created since $0 started:" |$TLOG find $ARCH_LOG_DIR -type f -name "$ARCH_LOG_FILE*" -newer $OLD -print \ >$TMP/$X.newer NEWER=`cat $TMP/$X.newer` if [ -n "$NEWER" ] ; then echo " New archive logs found: " |$TLOG cat $TMP/$X.newer|sed 's/^/ /' | $TLOG for ARCHIVED_LOG_FILE in $NEWER ; do ARCHIVED_LOG_FILE_BASENAME=`basename $ARCHIVED_LOG_FILE` BACKUP_COPY_NAME="backup.$ARCHIVED_LOG_FILE_BASENAME" cp -p $ARCHIVED_LOG_FILE $CWD/$BACKUP_COPY_NAME [ $? -ne 0 ] && Log_error 1 "Error copying $ARCHIVED_LOG_FILE to $CWD" done COMPRESS_LIST=`ls $CWD/backup.${ARCH_LOG_FILE}* |egrep -v '\.gz$|\.z$|\.Z$'` $COMPRESS -f $COMPRESS_LIST 2>/dev/null [ $? -ne 0 ] && Log_error 1 "Error compressing $CWD/${ARCH_LOG_FILE}\*" else echo " NO archive logs made since this backup started." |$TLOG fi else echo " No logs: $ORACLE_SID set to NOARCHIVELOG." |$TLOG fi else Log_error 1 "$CWD/$LOGFILE_LIST: File not found" fi if [ -f $CWD/$DUMPDEST_LIST ] ; then echo " Creating controlfile trace file: $CWD/recreate-controlfile.txt" |$TLOG DUMPDEST=`cat $CWD/$DUMPDEST_LIST|sed "s-\?-$ORACLE_HOME-"` #Find tracefile and copy it TRACEFILE=`find $DUMPDEST -newer $DUMPDEST/tracefile.timefile.empty \ -type f -print|tail -1`
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -