#!/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 <this file name>.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 <userid>/<passwd>@<net service name>'" 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
