#!/usr/bin/ksh
#File-name: rman_backup_arch.ksh
#---------------------------------------------------------------------
# Author: Larry Roberts 6/03/2004
#       : Changed to work using RMAN
# Change: Larry Roberts 11/24/2004
#       : Changed to work Oracle8i, Oracle9i and Oracle10G
# E-mail: lroberts@tandbergtv.com
# W-page: http://www.tandbergtv.com
#---------------------------------------------------------------------
# Online, rman backup - will run a full or incremental backup
# of the database.
# Should be run in the following way in crontab
# DEVICE_TYPE should be DISK or TAPE
# INC_LEVEL should be 0,1, or 2
#  0 6,10,14,18,22 * * * /usr/local/n2bb/backup/scripts/rman_backup_arch.ksh DEVICE_TYPE
#---------------------------------------------------------------------
#
#---------------------------------------------------------------------
#--- Info highlighted like this is the start of a function -----------
#---------------------------------------------------------------------
#
#----------------------------------------------
# Info highlighted like this is for doco only
#----------------------------------------------
#
########## These values can be changed ##################################
export retention_days=14
export backup_home=/usr/local/n2bb/backup
export MAIL_LIST="support@n2bb.com"
#######################################################################
#DEVICE_TYPE to contain backup
DEVICE_TYPE=$1; export DEVICE_TYPE

# REWIND TAPE DRIVE
    TAPE_DRIVE=/dev/rmt/0m
# NO REWIND TAPE DRIVE
    TAPE_DRIVE_NR=/dev/rmt/0mn
#
if test -f /var/opt/oracle/oratab
then
    ORATAB=/var/opt/oracle/oratab
fi
if test -f /etc/oratab
then
    ORATAB=/etc/oratab
fi
export ORATAB
#------------------------------------------------------------------------
#----------------------- Initialization ---------------------------------
#------------------------------------------------------------------------
function Initialization
{
########################################################################
export l_date=`date '+%Y%m%d'`
export MAILX="/usr/ucb/Mail"
export BOX=`uname -n`
export BACKUP_DIR=$backup_home
if test ! -d ${BACKUP_DIR}/ARCH
then
        mkdir ${BACKUP_DIR}/ARCH
        chmod 755 ${BACKUP_DIR}/ARCH
fi
BACKUP_DIR=${BACKUP_DIR}/ARCH
l_log=${BACKUP_DIR}/${ORACLE_SID}_arch_${l_date}.log
export RMAN_LOG=${BACKUP_DIR}/rman_${ORACLE_SID}_arch_${l_date}.log
NEWDIR="arch_backup_${l_date}"
    if test ! -d ${BACKUP_DIR}/${NEWDIR}
    then
        mkdir ${BACKUP_DIR}/${NEWDIR}
        chmod 755 ${BACKUP_DIR}/${NEWDIR}
        export FIRST_TIME=YES
    fi
BACKUP_DIR=${BACKUP_DIR}/${NEWDIR}
export dbidlist=${BACKUP_DIR}/dbid.lst
export oracle_version=${BACKUP_DIR}/oraclever.lst
echo "Initializing all variables" >> $l_log
echo `date '+%m/%d/%y %A %X'` "*** log BEGIN ***" >> $l_log
echo "----------------------------------------------------------------" >> $l_log
echo "Script      : "$0 >> $l_log
echo "Database    : "$ORACLE_SID >> $l_log
echo "Server      : "`uname -n` >> $l_log
echo "----------------------------------------------------------------" >> $l_log

} #END Initialization

############################################################
# things to do before exiting.  any exit from the program  #
# should be done by calling do_exit with a numeric argument#
# a non-numeric argument (or none at all) will generate an #
# error of its own, so be careful                          #
############################################################
function do_exit
{
    exit $1

} #END do_exit

#------------------------------------------------------------------------
#------------------ Verify a database is up and running -----------------
#------------------------------------------------------------------------
function verifyDatabase
{
echo "Verifying database up and running" >> $l_log
STATUS=`ps -fu oracle | grep "ora_[a-z]*_${ORACLE_SID}" `
if [ $? != 0 ]; then
        echo " DATABASE ${ORACLE_SID} WAS NOT RUNNING" >> $l_log
        db_not_up=0
else
        db_not_up=1
fi
echo "Running sqlplus to obtain Database DBID" >> $l_log
sqlplus /nolog <<EOF
        connect / as sysdba
        set termout off
        set pagesize 0
        set heading off
        set feedback off

        spool ${dbidlist};
        select dbid,log_mode from v\$database;
        spool off;
        spool $oracle_version;
        select substr(banner,1,8) from v\$version where banner like 'Oracle%';
        spool off;
        exit;
EOF

SED="sed -e '/^SQL/d'  \$dbidlist"
eval $SED | while read DB LM
do
    export DBID=$DB
    export LOGMODE=$LM
done

SED="sed -e '/^SQL/d' -e '/^ /d' \$oracle_version"
eval $SED | while read OV
do
    export ORACLE_VER=$OV
done

if [ "${LOGMODE}" = "NOARCHIVELOG" ]
then
   db_not_up=2
fi

} # END verifyDatabase

#------------------------------------------------------------------------
#----------------------- RMAN execution ---------------------------------
#------------------------------------------------------------------------
function run_rman
{

if [ "${ORACLE_VER}" != "Oracle8i" ]
then
echo "Check to see if controlfile is already backed up..if so delete first" >> $l_log
if test -f ${BACKUP_DIR}/${ORACLE_SID}_controlfile_${l_date}.ctl
then
   rm ${BACKUP_DIR}/${ORACLE_SID}_controlfile_${l_date}.ctl
fi

echo "run crosscheck on archivelog to see if any expired" >> $l_log
rman log=${RMAN_LOG} >> $l_log <<EOF
   set DBID = $DBID;
   connect target /
RUN{
    crosscheck archivelog all;
    delete noprompt expired archivelog all;
  }
EOF

echo "Running RMAN to backup archivelogs" >> $l_log
rman log=${RMAN_LOG} >> $l_log <<EOF1
   set DBID = $DBID;
   connect target /
RUN{
        backup format '${BACKUP_DIR}/${ORACLE_SID}_${l_date}_%t.arc'
                filesperset=10
                archivelog all skip inaccessible;
        backup (current controlfile format '${BACKUP_DIR}/${ORACLE_SID}_controlfile_${l_date}.ctl');
  }
EOF1
else
echo "Running RMAN to backup archivelogs" >> $l_log
rman target / nocatalog log=${RMAN_LOG} >> $l_log <<EOF1
RUN{
        backup format '${BACKUP_DIR}/${ORACLE_SID}_${l_date}_%t.arc'
                filesperset=10
                archivelog all
                current controlfile;
  }
EOF1
fi

#------------------------------------------------
#           Send Emails to whomever
#------------------------------------------------
#if [ $? != 0 ]; then
#cat ${RMAN_LOG} | $MAILX -s "RMAN backup of ${ORACLE_SID} archivelogs on ${BOX} failed" ${MAIL_LIST}
#else
#$MAILX -s "RMAN backup of ${ORACLE_SID} archivelogs on ${BOX} ran OK" ${MAIL_LIST}
#fi

} #END run_rman

#------------------------------------------------------------------------
#----------- Check Tape Drive for tape mounted and rewound --------------
#------------------------------------------------------------------------
function checkTape
{
echo "Checking the Status of Tape Drive ${TAPE_DRIVE_NR}" >> $l_log
MSG_CNT=0
while
   mt -f ${TAPE_DRIVE_NR} status
   tapeStatus=${?}
   [ "${tapeStatus}" != "0" ]
   do
      if [ "${MSG_CNT}" != "0" ]
         then echo "Message: Tape is not in drive: ${TAPE_DRIVE_NR}" >> $l_log
      fi

     sleep 60

      MSG_CNT=`expr ${MSG_CNT} + 1`
      if [ "${MSG_CNT}" = "30" ]
         then echo "Message: Tape was not in drive: ${TAPE_DRIVE_NR}"  >> $l_log
              echo "Checked for 30 minutes.\n"
              echo "Terminating\n"
              do_exit 1
      fi
   done
}  # END  checkTape

#---------------------------------------------------------------------
# Copy backup Directory to tape --------------------------------------
#---------------------------------------------------------------------
function CopytoTape
{

#need to check to see if this is first time archs are written during the day
if [ "${FIRST_TIME}" != "YES" ]
then
#need to rewind tape 1 file so new archs are copied with old ones.
    mt -f /dev/rmt/0mn nbsf 1
fi

echo "Copying Directory $BACKUP_DIR to tape." >> $l_log
    tar -cvf ${TAPE_DRIVE_NR} ${BACKUP_DIR}

#In order to run the below one must have some Media Manager Software installed
#and linked properly with oracle .

echo "Successfully Copied Directory $BACKUP_DIR to tape." >> $l_log

} #END CopytoTape

#------------------------------------------------------------------------
# print a footer into a log file
#------------------------------------------------------------------------
function Print_Footer
{
    echo "----------------------------------------------------------------" >> $l_log
    echo `date '+%m/%d/%y'` `date '+%H:%M:%S'` "*** log END ***" >>  $l_log
    echo "Check the $l_log for process errors"
    echo "Check the $RMAN_LOG for any rman errors"

} #END Print_Footer

#------------------------------------------------------------------------
#----------------------- Main Search of Oratab --------------------------
#------------------------------------------------------------------------
#if [ "${HOSTTYPE}" = "sparc" ]
#then
#   if [ "${LOGNAME}" != "oracle" ]
#   then
#     echo "MUST run this as the oracle user"
#     do_exit 1
#   fi
#else
#   oracleuid=`grep oracle /etc/passwd | cut -d ":" -f 3`
#   loginuid=`id -u`
#   if [ "${loginuid}" != "${oracleuid}" ]
#   then
#      echo "MUST run this as the oracle user"
#      do_exit 1
#   fi
#fi

if [ "${DEVICE_TYPE}" = "TAPE" ]
then
checkTape
fi

cat $ORATAB | while read LINE
do
    case $LINE in
        \#*)                ;;        #comment-line in oratab
        *)
#       Proceed only if third field is 'Y'.
        if [ "`echo $LINE | awk -F: '{print $3}' -`" = "Y" ] ; then
            ORACLE_SID=`echo $LINE | awk -F: '{print $1}' -`
            if [ "$ORACLE_SID" = '*' ] ; then
                ORACLE_SID=""
            fi
#           Called programs use same database ID
            export ORACLE_SID
            ORACLE_HOME=`echo $LINE | awk -F: '{print $2}' -`
#           Called scripts use same home directory
            export ORACLE_HOME
#           Put $ORACLE_HOME/bin into PATH and export.
            PATH=$ORACLE_HOME/bin:/bin:/usr/bin:/etc ; export PATH
            LD_LIBRARY_PATH=${ORACLE_HOME}/lib ; export LD_LIBRARY_PATH
            Initialization
            verifyDatabase
            if [ "${db_not_up}" != "0" ]
            then
            run_rman

            Print_Footer

            fi
        fi
    esac
done

if [ "${DEVICE_TYPE}" = "TAPE" ]
then
   echo "done"
   CopytoTape
   export FIRST_TIME=NO
fi

do_exit 0
#-----------------------------------------------------
# End of file

