#!/bin/sh # $Header$ # #bcpyrght #*************************************************************************** # $Copyright: Copyright (c) 2022 Veritas Technologies LLC. All rights reserved $ #*************************************************************************** #ecpyrght # # Note: Only make modifications to a copy of this file. Changes to this file # are lost when this example is overwritten during NetBackup upgrade. # Delete this comment from the copy. # # ----------------------------------------------------------------------------- # pit_database_restore.sh # ----------------------------------------------------------------------------- # This script uses Recovery Manager to restore and recover a database to # the point in time immediately before a user error occurred. It is assumed # that this script will be executed by user root. In order for RMAN to work # properly we switch user (su -) to the oracle dba account before execution. # If this script runs under a user account that has Oracle dba privilege, # it will be executed using this user's account # ----------------------------------------------------------------------------- # ----------------------------------------------------------------------------- # Log the start of this script to both the stdout/obk_stdout # and stderr/obk_stderr. # ----------------------------------------------------------------------------- echo "==== $0 started on `date` ==== stdout" echo "==== $0 started on `date` ==== stderr" 1>&2 DEBUG=0 if [ "$DEBUG" -gt 0 ]; then set -x fi # --------------------------------------------------------------------------- # Put output in .out. Change as desired. # Note: output directory requires write permission. # --------------------------------------------------------------------------- RMAN_LOG_FILE=${0}.out # ----------------------------------------------------------------------------- # Delete the log file before each execution so that it does not grow unbounded. # Remove or comment these lines if all historical output must be retained or if # the log file size is managed externally. # ----------------------------------------------------------------------------- if [ -f "$RMAN_LOG_FILE" ]; then rm -f "$RMAN_LOG_FILE" fi # ----------------------------------------------------------------------------- # Initialize the log file. By default it is readable by the DBA and other # users. Restrict the permissions as needed. # ----------------------------------------------------------------------------- echo >> $RMAN_LOG_FILE chmod 644 $RMAN_LOG_FILE # ----------------------------------------------------------------------------- # Redirect all stderr and stdout into the specified log file and also to # stdout. No output will appear on stderr (or in the obk_stderr). # ----------------------------------------------------------------------------- out=/tmp/`basename $0`.stdout.$$ trap "rm -f $out" EXIT SIGHUP SIGINT SIGQUIT SIGTRAP SIGKILL SIGUSR1 SIGUSR2 SIGPIPE SIGTERM SIGSTOP mkfifo "$out" tee -a $RMAN_LOG_FILE < "$out" & exec 1>&- 2>&- exec 1>"$out" 2>&1 # ----------------------------------------------------------------------------- # Log the start of this script to the log file and stdout. # Log any additional arguments to the script. # ----------------------------------------------------------------------------- echo "==== $0 started on `date` ====" echo "==== $0 $*" echo # *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* # *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* # # NOTE: User modifications should be made only below this point. # # USER CUSTOMIZABLE VARIABLE SECTION # # ORACLE_HOME - Oracle Home path # ORACLE_SID - Oracle Sid of the target database # ORACLE_USER - Oracle user with permissions to execute RMAN # ORACLE_TARGET_CONNECT_STR - Connect string for the target database # [user]/[password][@TNSalias] # RMAN_EXECUTABLE - Path to the rman executable # RMAN_SBT_LIBRARY - SBT library path; # on AIX see technote TECH194511. # RMAN_CATALOG - Recovery catalog option and connect string # NLS_LANG - Desired Language # NLS_DATE_FORMAT - Desired date format ORACLE_HOME=/home/oracle/app/oracle/product/12.1.0/dbhome_1 ORACLE_SID=noncdb12c ORACLE_USER=oracle ORACLE_TARGET_CONNECT_STR=sys/manager RMAN_EXECUTABLE=$ORACLE_HOME/bin/rman RMAN_SBT_LIBRARY="/usr/openv/netbackup/bin/libobk.so64" # Set the Recovery catalog to use. In This example we do not use a # Recovery Catalog. If you choose to use one, replace the option 'nocatalog' # with a "'catalog /@'" statement. RMAN_CATALOG="nocatalog" NLS_LANG=american NLS_DATE_FORMAT='YYYY-MM-DD:hh24:mi:ss' export ORACLE_HOME ORACLE_SID export NLS_LANG NLS_DATE_FORMAT # Note: Additional tuning may be desired to RMAN_SEND and CMD_INPUT below. # *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* # *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* # ----------------------------------------------------------------------------- # Determine the user which is executing this script. # ----------------------------------------------------------------------------- BACKUP_CUSER=`id |cut -d"(" -f2 | cut -d ")" -f1` # --------------------------------------------------------------------------- # NOTE: This script assumes that the database is off line (mount state). If # desired, this would be the place to verify that. # --------------------------------------------------------------------------- # ----------------------------------------------------------------------------- # Construct an RMAN SEND command when initiated from the master server. # This ensures that the resulting application backup jobs utilize the same # master server, client name, and policy name. # # If desired, initialize RMAN_SEND with additional NB_ORA_* variable=value # pairs. # # NOTE WHEN USING NET SERVICE NAME: When connecting to a database # using a net service name, you must use a send command or a parms operand to # specify environment variables. In other words, when accessing a database # through a listener, any environment variable set in this script are not # inherited by the Oracle channel processes because it is a child of the # listener process and not of this script. For more information on the # environment variables, please refer to the NetBackup for Oracle Admin. Guide. # ----------------------------------------------------------------------------- RMAN_SEND="" if [ "$NB_ORA_SERV" != "" ]; then RMAN_SEND="NB_ORA_SERV=${NB_ORA_SERV}" fi if [ "$NB_ORA_CLIENT" != "" ]; then if [ "$RMAN_SEND" != "" ]; then RMAN_SEND="${RMAN_SEND},NB_ORA_CLIENT=${NB_ORA_CLIENT}" else RMAN_SEND="NB_ORA_CLIENT=${NB_ORA_CLIENT}" fi fi if [ "$NB_ORA_POLICY" != "" ]; then if [ "$RMAN_SEND" != "" ]; then RMAN_SEND="${RMAN_SEND},NB_ORA_POLICY=${NB_ORA_POLICY}" else RMAN_SEND="NB_ORA_POLICY=${NB_ORA_POLICY}" fi fi if [ "$BACKUP_SCHEDULE" != "" ]; then if [ "$RMAN_SEND" != "" ]; then RMAN_SEND="${RMAN_SEND},NB_ORA_SCHED=${BACKUP_SCHEDULE}" else RMAN_SEND="NB_ORA_SCHED=${BACKUP_SCHEDULE}" fi fi if [ "$RMAN_SEND" != "" ]; then RMAN_SEND="SEND '${RMAN_SEND}';" fi # ----------------------------------------------------------------------------- # Call Recovery Manager to initiate the restore. # # Note: Any environment variables needed at run time by RMAN # must be set and exported within the CMDS variable. # ----------------------------------------------------------------------------- # The following scenario assumes: # o you wish to do an incomplete recovery due to an # application error which was made at a specific time # o the database is in the mount state # o there are 2 tape drives # o the NLS_LANG and NLS_DATE_FORMAT environment variables are set # o you are using a recovery catalog # # Note: It is highly advisable to backup the database immediately after # opening the database resetlogs. # # The following script restores and recovers the database to the time # immediately before the user error occurred. # # o restores the database files (to the original locations) # o recovers the datafiles by either using a combination # of incremental backups and redo, or just redo. # o Recovery Manager will complete the recovery when it # reaches the time specified. # o Opens the database resetlogs. # o Oracle recommends you backup your database after the # resetlogs (this is not shown in the example). # # # Ensure you set your NLS_LANG and NLS_DATE_FORMAT environment variables. # You can set these to whatever you wish - the example below keeps the date # format to the standard date format used for recovery. # # Ensure that the target database is in the mount state. To mount the # database you can start up sqlplus, and: # # sqlplus: # # sqlplus /nolog # SQL> connect sys/manager # Connected. # SQL> startup mount restrict pfile=/db/oracle/admin/ora102/pfile/initPROD/ora # # ----------------------------------------------------------------------------- # When needed, commands to debug the environment present in the subshell where # RMAN will be started. if [ "$DEBUG" -gt 0 ]; then ENV_COMMANDS=" echo ----- LIST OF DECLARED VARIABLES IN SUBSHELL ----- echo set | sort echo echo ----- LANGUAGE AND LOCALE ----- echo locale echo echo ----- PROCESS LIST ----- echo ps -ef echo" else ENV_COMMANDS="" fi # The RMAN commands to be executed. # NOTE: If the default shell for the ORACLE_USER is the C shell, then update # the export syntax as follows: # setenv ORACLE_HOME "$ORACLE_HOME" # setenv ORACLE_SID "$ORACLE_SID" # setenv NLS_LANG=$NLS_LANG # setenv NLS_DATE_FORMAT=$NLS_DATE_FORMAT CMDS=" export ORACLE_HOME=$ORACLE_HOME export ORACLE_SID=$ORACLE_SID export NLS_LANG=$NLS_LANG export NLS_DATE_FORMAT=$NLS_DATE_FORMAT echo echo ----- SUBSHELL ENV VARIABLES ----- echo env | sort | egrep '^ORACLE_|^NB_ORA_|^RMAN_|^BACKUP_|^TNS_' echo $ENV_COMMANDS echo ----- STARTING RMAN EXECUTION ----- echo $RMAN_EXECUTABLE target $ORACLE_TARGET_CONNECT_STR $RMAN_CATALOG" # Building the PARMS option for the RMAN channels if [ $RMAN_SBT_LIBRARY != "" ]; then RMAN_SBT_LIBRARY_PARMS="PARMS 'SBT_LIBRARY=$RMAN_SBT_LIBRARY'" else RMAN_SBT_LIBRARY_PARMS="" fi # The RMAN statements that are needed to perform the desired restore. # Add, delete, or modify the CMD_INPUT per the backup requirements for the # instance. CMD_INPUT="<< EOF SHOW ALL; RUN { # The 'set until time' command is in effect for all commands executed # between the { and } braces. This means both the restore and recover # will both be relative to that point-in-time. # Note that Recovery Manager is able to query the Recovery Catalog, # determine what the structure of the database was at that time, and # restore it. set until time '2015-06-11:14:30:00'; ALLOCATE CHANNEL ch00 TYPE 'SBT_TAPE' $RMAN_SBT_LIBRARY_PARMS; ALLOCATE CHANNEL ch01 TYPE 'SBT_TAPE' $RMAN_SBT_LIBRARY_PARMS; RESTORE DATABASE; # There is no need to manually catalog any archivelogs before the recovery, # as Recovery Manager does an implicit catalog resync from the current # control file. RECOVER DATABASE; sql 'alter database open resetlogs'; RELEASE CHANNEL ch00; RELEASE CHANNEL ch01; } EOF " # ----------------------------------------------------------------------------- # Print out the values of various variables matched by the following patterns. # ----------------------------------------------------------------------------- if [ "$DEBUG" -gt 0 ]; then echo ----- LIST OF DECLARED VARIABLES IN SCRIPT ----- echo set | sort echo fi echo echo "----- SCRIPT VARIABLES -----" echo set | sort | egrep '^ORACLE_|^NB_ORA_|^RMAN_|^BACKUP_|^TNS_' echo echo "----- RMAN CMD -----" echo echo "$CMDS" echo echo "----- RMAN INPUT -----" echo echo "$CMD_INPUT" echo # Sanity check the environment. if [ ! -x $RMAN_EXECUTABLE ]; then echo "ERR: $RMAN_EXECUTABLE: required executable not found!" 1>&2 exit 1 fi if [ ! -f `echo $RMAN_SBT_LIBRARY | cut -d'(' -f1` ]; then echo "ERR: $RMAN_SBT_LIBRARY: required library not found!" 1>&2 exit 1 fi echo "----- STARTING CMDS EXECUTION -----" echo if [ "$BACKUP_CUSER" = "root" ]; then su - $ORACLE_USER -c "$CMDS $CMD_INPUT" RSTAT=$? else /bin/sh -c "$CMDS $CMD_INPUT" RSTAT=$? fi # --------------------------------------------------------------------------- # Log the completion of this script to both stdout/obk_stdout # and stderr/obk_stderr. # --------------------------------------------------------------------------- if [ "$RSTAT" = "0" ]; then LOGMSG="ended successfully" else LOGMSG="ended in error" fi echo echo "==== $0 $LOGMSG on `date` ==== stdout" echo "==== $0 $LOGMSG on `date` ==== stderr" 1>&2 echo exit $RSTAT