Skip to main content

Template AIX Scripts

Druva provides template scripts that you can use to back up databases on the Oracle RMAN Database host.

oracle_rman_archivelog_backup_AIX.sh

Click here to view script

#!/usr/bin/bash

set -x
if [ "$#" -ne 2 ]; then
echo ""
echo "Usage: $0 <backup_store_IP> <backup_mount_name>"
echo ""
echo " <backup_store_IP> : IP address of the Phoenix Backup Store"
echo " <backup_mount_name> : Name of the backup mount configured in Phoenix, e.g. mount1"
exit 1
fi

BACKUP_STORE_IP=$1
BACKUP_MOUNT=$2

PARALLELISM=1

if [[ -z "${ORACLE_HOME}" ]];
then
echo "Environment variable ORACLE_HOME not set... exiting"
exit 1
fi

if [[ -z "${ORACLE_SID}" ]];
then
echo "Environment variable ORACLE_SID not set... exiting"
exit 1
fi

SID=${ORACLE_SID}

# --- ENHANCED FAILURE NOTIFICATION TRAP ---
export RMAN_SCRIPT_STAGE="Initialization"
export RMAN_SCRIPT_ERROR_MSG="Unexpected termination during initialization"
export RMAN_SCRIPT_RESOLUTION_MSG="Check export service logs or contact Druva Support"

rman_script_failure_notify() {
local ec="${1:-1}"

# Only fire the alert if the exit code is strictly greater than 0
[ "$ec" -eq 0 ] && return 0

local stage="${RMAN_SCRIPT_STAGE}"
local sid="${ORACLE_SID}"
local err_msg="${RMAN_SCRIPT_ERROR_MSG}"
local resolution_msg="${RMAN_SCRIPT_RESOLUTION_MSG}"

# Escape internal double quotes and newlines to prevent JSON payload corruption
local stage_escaped="${stage//\"/\\\"}"
local sid_escaped="${sid//\"/\\\"}"
local err_msg_escaped="${err_msg//\"/\\\"}"
err_msg_escaped="${err_msg_escaped//$'\n'/ }" # Replace newlines with spaces
local resolution_msg_escaped="${resolution_msg//\"/\\\"}"
resolution_msg_escaped="${resolution_msg_escaped//$'\n'/ }" # Replace newlines with spaces

# Construct JSON payload natively using printf
local body
body=$(printf '{"exit_code":%d,"failure_stage":"%s","db_sid":"%s","error_msg":"%s","resolution_msg":"%s"}' \
"$ec" "$stage_escaped" "$sid_escaped" "$err_msg_escaped" "$resolution_msg_escaped")

# Network-hardened API call with a 30-second maximum timeout ceiling
curl -sS --max-time 30 -X POST "http://${BACKUP_STORE_IP}:9090/druva-phoenix/v1/mounts/${BACKUP_MOUNT}/rmanbackup/failure-alert" \
-H "Content-Type: application/json" \
-d "$body" >/dev/null 2>&1 || true
}

# Register trap to catch any exit and pass the true exit code
trap 'rman_script_failure_notify $?' EXIT
# ------------------------------------------

export RMAN_SCRIPT_STAGE="Validate Backup Request"
echo "Validating backup request"
validate_resp=$(curl -X GET http://$BACKUP_STORE_IP:9090/druva-phoenix/v1/mounts/$BACKUP_MOUNT/1.2/backup 2> /dev/null)
if [ $? -ne 0 ];
then
export RMAN_SCRIPT_ERROR_MSG="Backup validation request failed with response: $validate_resp"
echo "Request to validate phoenix backup failed... exiting"
echo "Response from Phoenix Backup Store: "$validate_resp
exit 1
fi

VALIDATE_ERROR_CODE=$(echo "$validate_resp" | awk -F "error_code" '{print $2}' | cut -d ':' -f2 | cut -d ',' -f1)
if [ "$VALIDATE_ERROR_CODE" -ne 0 ];
then
export RMAN_SCRIPT_ERROR_MSG="Backup validation failed (error_code: ${VALIDATE_ERROR_CODE})"
echo "Response from Phoenix Backup Store: "$validate_resp
echo "Request to validate Phoenix backup failed... exiting"
exit 1
fi

# Sample output format
# {"error_code":0,"error_msg":"","result":{"is_reached_max_snapshots":false,"mount_name":"m2"}}
IS_REACHED_MAX_SNAPSHOTS=$(echo "$validate_resp" | awk -F "is_reached_max_snapshots" '{print $2}' | cut -d ',' -f1 | cut -d ':' -f2)
if [ "$IS_REACHED_MAX_SNAPSHOTS" = "false" ];
then
echo "Validation for phoenix backup succeeded"
else
export RMAN_SCRIPT_ERROR_MSG="Backup mount reached max snapshot limit"
export RMAN_SCRIPT_RESOLUTION_MSG="Increase max snapshots limit or wait for pending uploads"
echo "Response from Phoenix Backup Store: "$validate_resp
echo "Validation for phoenix backup failed... exiting"
exit 1
fi

export RMAN_SCRIPT_STAGE="Start Phoenix Backup"
echo "Notifying Phoenix to start backup - Phoenix Backup Store=$BACKUP_STORE_IP mount name=$BACKUP_MOUNT"

res=$(curl -X POST http://$BACKUP_STORE_IP:9090/druva-phoenix/v1/mounts/$BACKUP_MOUNT/backup 2> /dev/null)
if [ $? -ne 0 ];
then
export RMAN_SCRIPT_ERROR_MSG="Failed to start Phoenix Backup session"
echo "Request to start phoenix backup failed... exiting"
echo "Response from Phoenix Backup Store: "$res
exit 1
fi

# Sample output format
# {"error_code":4295622665,"error_msg":"Backup mount does not exist on Export Service.","result":{"mount_name":"mount4","mount_path":""}}
ERROR_CODE=$(echo "$res" | awk -F "error_code" '{print $2}' | cut -d ':' -f2 | cut -d ',' -f1)
if [ "$ERROR_CODE" -ne 0 ];
then
export RMAN_SCRIPT_ERROR_MSG="Phoenix Backup init failed (error_code: ${ERROR_CODE})"
echo "Response from Phoenix Backup Store: "$res
echo "Request to start Phoenix backup failed... exiting"
exit 1
fi

export RMAN_SCRIPT_STAGE="Mount Phoenix Backup Store"
REMOTE_MOUNTPOINT=$BACKUP_STORE_IP:$(echo "$res" | awk -F "mount_path" '{print $2}' | cut -d '"' -f3)
remote_name=$(echo "$res" | awk -F "mount_path" '{print $2}' | cut -d '"' -f3)

RMANBACKUP_MOUNTPOINT=$(FoundMount=0
count=0
while read line
do
line1=$(echo ${line} | sed 's/\s\+//g' | tr -d "\t" | sed '/^$/d' | sed "s/ //g")
ifMount=$(echo ${line1} | grep "^/" | grep ":$" | wc -l)
if [[ ${ifMount} -gt 0 ]]
then
MountName=$(echo ${line1} | sed 's/://g')
FoundMount=1
count=1
NodeName=""
DevName=""
fi

if [[ FoundMount -eq 1 ]]
then

ifDev=$(echo ${line1} | grep "^dev=" | wc -l)
if [[ ${ifDev} -eq 1 ]]
then
DevName=$(echo ${line1} | sed 's/dev=//g')
count=$(echo ${count} + 1 | bc)
fi

ifNodeName=$(echo ${line1} | grep "^nodename=" | wc -l)
if [[ ${ifNodeName} -eq 1 ]]
then
NodeName=$(echo ${line1} | sed 's/nodename=//g')
count=$(echo ${count} + 1 | bc)
fi

fi

if [[ ${count} -eq 3 ]]
then
echo "${MountName} ${DevName} ${NodeName}"
FoundMount=0
count=0
NodeName=""
DevName=""
fi

done < /etc/filesystems | grep ${BACKUP_STORE_IP} | grep ${remote_name} | awk '{print $1}')

if [ -z "$RMANBACKUP_MOUNTPOINT" ];
then
export RMAN_SCRIPT_ERROR_MSG="Mount entry missing from /etc/filesystems"
export RMAN_SCRIPT_RESOLUTION_MSG="Add mount entry to /etc/filesystems"
echo "Entry for Phoenix Backup Store mount not found in /etc/filesystems... exiting"
exit 1
fi

remote_mnt=$(echo ${REMOTE_MOUNTPOINT} | sed 's/:/ /g')
ACTUAL_MOUNTPOINT=$(mount | grep "^$remote_mnt" | sed 's/\s\+/ /g' | cut -d " " -f3 2> /dev/null)

if [ -z "$ACTUAL_MOUNTPOINT" ];
then
mount "$RMANBACKUP_MOUNTPOINT" 2> /dev/null
if [ $? -ne 0 ];
then
export RMAN_SCRIPT_ERROR_MSG="Failed to mount backup store"
export RMAN_SCRIPT_RESOLUTION_MSG="Verify mount entry in /etc/filesystems"
echo "Unable to mount $RMANBACKUP_MOUNTPOINT... exiting"
exit 1
fi
else
RMANBACKUP_MOUNTPOINT=$ACTUAL_MOUNTPOINT
fi

export PATH=$ORACLE_HOME/bin:$PATH
arch_backup () {

export RMAN_SCRIPT_STAGE="Create Archivelogs Backup Directory"
if [ ! -e "$RMANBACKUP_MOUNTPOINT/$SID/archivelogs" ]
then
mkdir -p "$RMANBACKUP_MOUNTPOINT/$SID/archivelogs"
if [ $? -eq 0 ];
then
echo "Created directory for archivelogs backup $RMANBACKUP_MOUNTPOINT/$SID/archivelogs"
else
export RMAN_SCRIPT_ERROR_MSG="Failed to create archivelogs directory"
export RMAN_SCRIPT_RESOLUTION_MSG="Check directory permissions and writability"
echo "Oracle user does not have permission for $RMANBACKUP_MOUNTPOINT/$SID directory... exiting"
exit 1
fi
elif [ ! -d "$RMANBACKUP_MOUNTPOINT/$SID/archivelogs" ];
then
export RMAN_SCRIPT_ERROR_MSG="Path conflict: archivelogs path is a file, expected directory"
export RMAN_SCRIPT_RESOLUTION_MSG="Remove conflicting file and retry"
echo "$RMANBACKUP_MOUNTPOINT/$SID is not a directory... exiting"
exit 1
fi

LOG_FILE_DIR=$RMANBACKUP_MOUNTPOINT/'_workspace/RMAN_Logs'
echo "Creating Log File Dir: =$RMANBACKUP_MOUNTPOINT'/_workspace/RMAN_Logs'"

if [ ! -e "$LOG_FILE_DIR" ]
then
mkdir -p "$LOG_FILE_DIR"
if [ $? -eq 0 ];
then
echo "Created log directory for oracle backup $LOG_FILE_DIR"
else
export RMAN_SCRIPT_ERROR_MSG="Failed to create RMAN log directory"
export RMAN_SCRIPT_RESOLUTION_MSG="Check directory permissions and writability"
echo "Oracle user does not have permission for $LOG_FILE_DIR directory... exiting"
exit 1
fi
fi

echo -n > "$LOG_FILE_DIR/archivelogs_backup.log"
touch "$RMANBACKUP_MOUNTPOINT/_workspace/" 2>/dev/null
if [ $? -ne 0 ];
then
export RMAN_SCRIPT_ERROR_MSG="Failed to write to workspace folder"
export RMAN_SCRIPT_RESOLUTION_MSG="Check directory permissions and writability"
echo "$RMANBACKUP_MOUNTPOINT directory is not writable.. exiting"
exit 1
fi

# Checking if any of the Full/Diff backup is currently running and PID is active.
echo "Checking for backup lock file"
export RMAN_SCRIPT_STAGE="Check for Backup Lock File"
export BKP_CONTINUE=0
is_lock_file_present=$(find "${RMANBACKUP_MOUNTPOINT}" -type f -name ".RMAN_FULL_lock_*" | wc -l)
if [[ ${is_lock_file_present} -ne 0 ]]
then
for _lock_file in $(find "${RMANBACKUP_MOUNTPOINT}" -type f -name ".RMAN_FULL_lock_*" | xargs)
do
_pid=$(echo "${_lock_file}" | cut -d"_" -f4)
is_pid_proc_running=$(ps -ef | grep "${_pid}" | grep -v grep | wc -l)
if [[ ${is_pid_proc_running} -ne 0 ]]
then
echo "[INFO] Full backup Lock File: ${_lock_file} is present and PID is active"
export BKP_CONTINUE=1
else
echo "[INFO] Full backup Lock File: ${_lock_file} is present and PID is NOT active"
echo "Deleting ${_lock_file}"
rm "${_lock_file}"
if [ -e "${_lock_file}" ]
then
echo "ERROR deleting file ${_lock_file}"
echo "Exiting Log backup"
export BKP_CONTINUE=1
fi
fi
done

if [[ ${BKP_CONTINUE} -eq 1 ]]
then
export RMAN_SCRIPT_ERROR_MSG="Skipping backup: active RMAN backup or lock file present"
export RMAN_SCRIPT_RESOLUTION_MSG="Wait for active backup to finish or remove stale lock file"
echo "[WARNING] There is full backup running or the lock file for Full/diff backup is present"
echo "[ERROR] Exiting the current Log backup"
exit 5
fi
fi

echo "Starting with RMAN backup"
RMANBACKUP_MOUNTPOINT_FULL=$RMANBACKUP_MOUNTPOINT/$SID

export RMAN_SCRIPT_STAGE="Request RMAN Snapshot for Archivelog Backup"
res_rmanbackup=$(curl -X POST http://$BACKUP_STORE_IP:9090/druva-phoenix/v1/mounts/$BACKUP_MOUNT/${SID}/archivelog/rmanbackup 2> /dev/null)
if [ $? -ne 0 ];
then
export RMAN_SCRIPT_ERROR_MSG="Failed to request RMAN snapshot"
export RMAN_SCRIPT_RESOLUTION_MSG="Verify backup mount configuration"
echo "Request to start phoenix backup failed... exiting"
echo "Response from Phoenix Backup Store: "$res_rmanbackup
exit 1
fi

echo "Response RMAN Backup: ${res_rmanbackup}"

SNAPSHOT_NAME=$(echo "$res_rmanbackup" | awk -F "snap_name" '{print $2}' | cut -d '"' -f3)
if [ -z "$SNAPSHOT_NAME" ];
then
export RMAN_SCRIPT_ERROR_MSG="Failed to get snapshot name"
export RMAN_SCRIPT_RESOLUTION_MSG="Verify backup mount configuration"
echo "Failed to get Snapshot name. Exiting. Please check Export Service Logs in PBS"
exit 1
fi

echo "Snapshot to be created ${SNAPSHOT_NAME}"

export RMAN_SCRIPT_STAGE="Run RMAN Backup"
RMAN_LOGFILE=$LOG_FILE_DIR'/rman_archivelog_backup_'${SNAPSHOT_NAME}_${ORACLE_SID}'.log'
echo -n > "$RMAN_LOGFILE"
echo "RMAN Logfile: ${RMAN_LOGFILE}"

rman log="$RMAN_LOGFILE" 2> /dev/null << EOF
connect target /
set echo on;

configure backup optimization on;
configure controlfile autobackup on;
configure device type disk parallelism ${PARALLELISM} BACKUP TYPE TO COPY;
configure datafile backup copies for device type disk to 1;
configure archivelog backup copies for device type disk to 1;
configure controlfile autobackup format for device type disk to '${RMANBACKUP_MOUNTPOINT_FULL}/archivelogs/arch_controlfile_%d_%F.bkp';

run
{
sql 'alter system archive log current';
backup as backupset format '${RMANBACKUP_MOUNTPOINT_FULL}/archivelogs/%d_%h_%e_%s_%t.arc' archivelog all not backed up;

#Force is to ignore I/O errors
delete noprompt obsolete device type disk;
delete force NOPROMPT expired copy;
delete force NOPROMPT expired backup;
#adding this command to delete backups older than 5 days
DELETE FORCE NOPROMPT BACKUP COMPLETED BEFORE 'sysdate-5';

crosscheck backup;
crosscheck copy;
}

configure backup optimization clear;
configure controlfile autobackup clear;
exit
EOF

RMAN_EXIT_STATUS=$?
if [ $RMAN_EXIT_STATUS -ne 0 ];
then
export RMAN_SCRIPT_ERROR_MSG="RMAN backup failed (exit_code: ${RMAN_EXIT_STATUS})"
export RMAN_SCRIPT_RESOLUTION_MSG="Check RMAN logs and fix the issue"
echo ""
echo "rman failed with status $RMAN_EXIT_STATUS.. exiting"
exit 1
fi

export RMAN_SCRIPT_STAGE="Upload RMAN Logs"
echo "Notifying Phoenix to upload RMAN Logs"

rman_uploadlog_res=$(curl -X POST -H "Content-Type: multipart/form-data" -F "file=@$LOG_FILE_DIR/rman_archivelog_backup_${SNAPSHOT_NAME}_${ORACLE_SID}.log" -F mountpoint=$RMANBACKUP_MOUNTPOINT -F platform=aix http://$BACKUP_STORE_IP:9090/druva-phoenix/v1/mounts/$BACKUP_MOUNT/uploadlog 2> /dev/null)
if [ $? -ne 0 ];
then
echo "Request to send RMAN Logs failed..."
echo "Response from Phoenix Backup Store: "$rman_uploadlog_res
fi

export RMAN_SCRIPT_STAGE="End Backup"
echo "Notifying Phoenix to end backup"
final_res=$(curl -X PUT http://$BACKUP_STORE_IP:9090/druva-phoenix/v1/mounts/$BACKUP_MOUNT/backup 2> /dev/null)

if [ $? -ne 0 ];
then
export RMAN_SCRIPT_ERROR_MSG="Failed to end Phoenix Backup with response: $final_res"
export RMAN_SCRIPT_RESOLUTION_MSG="Verify export service is reachable and check its logs"
echo "Request to end phoenix backup failed... exiting"
echo "Response from Phoenix Backup Store: "$final_res
exit 1
fi

ERROR_CODE=$(echo "$final_res" | awk -F "error_code" '{print $2}' | cut -d ':' -f2 | cut -d ',' -f1)
if [ "$ERROR_CODE" -ne 0 ];
then
export RMAN_SCRIPT_ERROR_MSG="Failed to end Phoenix Backup (error_code: ${ERROR_CODE})"
export RMAN_SCRIPT_RESOLUTION_MSG="Verify export service is reachable and check its logs"
echo "Response from Phoenix Backup Store: "$final_res
echo "Request to start Phoenix backup failed... exiting"
exit 1
fi
echo "$final_res"

echo "Exiting with successful status"
}

# Main
arch_backup

oracle_rman_data_backup_AIX.sh

Click here to view script

#!/usr/bin/bash

if [ "$#" -ne 2 ]; then
echo ""
echo "Usage: $0 <backup_store_IP> <backup_mount_name>"
echo ""
echo " <backup_store_IP> : IP address of the Phoenix Backup Store"
echo " <backup_mount_name> : Name of the backup mount configured in Phoenix, e.g. mount1"
exit 1
fi

BACKUP_STORE_IP=$1
BACKUP_MOUNT=$2

PARALLELISM=1

if [[ -z "${ORACLE_HOME}" ]];
then
echo "Environment variable ORACLE_HOME not set... exiting"
exit 1
fi

if [[ -z "${ORACLE_SID}" ]];
then
echo "Environment variable ORACLE_SID not set... exiting"
exit 1
fi
SID=${ORACLE_SID}

# --- ENHANCED FAILURE NOTIFICATION TRAP ---
export RMAN_SCRIPT_STAGE="Initialization"
export RMAN_SCRIPT_ERROR_MSG="Unexpected termination during initialization"
export RMAN_SCRIPT_RESOLUTION_MSG="Check export service logs or contact Druva Support"

rman_script_failure_notify() {
local ec="${1:-1}"

# Only fire the alert if the exit code is strictly greater than 0
[ "$ec" -eq 0 ] && return 0

local stage="${RMAN_SCRIPT_STAGE}"
local sid="${ORACLE_SID}"
local err_msg="${RMAN_SCRIPT_ERROR_MSG}"
local resolution_msg="${RMAN_SCRIPT_RESOLUTION_MSG}"

# Escape internal double quotes and newlines to prevent JSON payload corruption
local stage_escaped="${stage//\"/\\\"}"
local sid_escaped="${sid//\"/\\\"}"
local err_msg_escaped="${err_msg//\"/\\\"}"
err_msg_escaped="${err_msg_escaped//$'\n'/ }" # Replace newlines with spaces
local resolution_msg_escaped="${resolution_msg//\"/\\\"}"
resolution_msg_escaped="${resolution_msg_escaped//$'\n'/ }" # Replace newlines with spaces

# Construct JSON payload natively using printf
local body
body=$(printf '{"exit_code":%d,"failure_stage":"%s","db_sid":"%s","error_msg":"%s","resolution_msg":"%s"}' \
"$ec" "$stage_escaped" "$sid_escaped" "$err_msg_escaped" "$resolution_msg_escaped")

# Network-hardened API call with a 30-second maximum timeout ceiling
curl -sS --max-time 30 -X POST "http://${BACKUP_STORE_IP}:9090/druva-phoenix/v1/mounts/${BACKUP_MOUNT}/rmanbackup/failure-alert" \
-H "Content-Type: application/json" \
-d "$body" >/dev/null 2>&1 || true
}

# Register trap to catch any exit and pass the true exit code
trap 'rman_script_failure_notify $?' EXIT
# ------------------------------------------

export RMAN_SCRIPT_STAGE="Validate Backup Request"
echo "Validating backup request"

validate_resp=$(curl -X GET http://$BACKUP_STORE_IP:9090/druva-phoenix/v1/mounts/$BACKUP_MOUNT/1.2/backup 2> /dev/null)
if [ $? -ne 0 ];
then
export RMAN_SCRIPT_ERROR_MSG="Backup validation request failed with response: $validate_resp"
echo "Request to validate phoenix backup failed... exiting"
echo "Response from Phoenix Backup Store: "$validate_resp
exit 1
fi

VALIDATE_ERROR_CODE=$(echo "$validate_resp" | awk -F "error_code" '{print $2}' | cut -d ':' -f2 | cut -d ',' -f1)
if [ "$VALIDATE_ERROR_CODE" -ne 0 ];
then
export RMAN_SCRIPT_ERROR_MSG="Backup validation failed (error_code: ${VALIDATE_ERROR_CODE})"
echo "Response from Phoenix Backup Store: "$validate_resp
echo "Request to validate Phoenix backup failed... exiting"
exit 1
fi

# Sample output format
# {"error_code":0,"error_msg":"","result":{"is_reached_max_snapshots":false,"mount_name":"m2"}}
IS_REACHED_MAX_SNAPSHOTS=$(echo "$validate_resp" | awk -F "is_reached_max_snapshots" '{print $2}' | cut -d ',' -f1 | cut -d ':' -f2)
if [ "$IS_REACHED_MAX_SNAPSHOTS" = "false" ];
then
echo "Validation for phoenix backup succeeded"
else
export RMAN_SCRIPT_ERROR_MSG="Backup mount reached max snapshot limit"
export RMAN_SCRIPT_RESOLUTION_MSG="Increase max snapshots limit or wait for pending uploads"
echo "Response from Phoenix Backup Store: "$validate_resp
echo "Validation for phoenix backup failed... exiting"
exit 1
fi

export RMAN_SCRIPT_STAGE="Start Phoenix Backup"
echo "Notifying Phoenix to start backup - Phoenix Backup Store=$BACKUP_STORE_IP mount name=$BACKUP_MOUNT"

res=$(curl -X POST http://$BACKUP_STORE_IP:9090/druva-phoenix/v1/mounts/$BACKUP_MOUNT/backup 2> /dev/null)
if [ $? -ne 0 ];
then
export RMAN_SCRIPT_ERROR_MSG="Failed to start Phoenix Backup session"
echo "Request to start phoenix backup failed... exiting"
echo "Response from Phoenix Backup Store: "$res
exit 1
fi

# Sample output format
# {"error_code":4295622665,"error_msg":"Backup mount does not exist on Export Service.","result":{"mount_name":"mount4","mount_path":""}}
ERROR_CODE=$(echo "$res" | awk -F "error_code" '{print $2}' | cut -d ':' -f2 | cut -d ',' -f1)
if [ "$ERROR_CODE" -ne 0 ];
then
export RMAN_SCRIPT_ERROR_MSG="Phoenix Backup init failed (error_code: ${ERROR_CODE})"
echo "Response from Phoenix Backup Store: "$res
echo "Request to start Phoenix backup failed... exiting"
exit 1
fi

export RMAN_SCRIPT_STAGE="Mount Phoenix Backup Store"
REMOTE_MOUNTPOINT=$BACKUP_STORE_IP:$(echo "$res" | awk -F "mount_path" '{print $2}' | cut -d '"' -f3)
remote_name=$(echo "$res" | awk -F "mount_path" '{print $2}' | cut -d '"' -f3)

RMANBACKUP_MOUNTPOINT=$(FoundMount=0
count=0
while read line
do
line1=$(echo ${line} | sed 's/\s\+//g' | tr -d "\t" | sed '/^$/d' | sed "s/ //g")
ifMount=$(echo ${line1} | grep "^/" | grep ":$" | wc -l)
if [[ ${ifMount} -gt 0 ]]
then
MountName=$(echo ${line1} | sed 's/://g')
FoundMount=1
count=1
NodeName=""
DevName=""
fi

if [[ FoundMount -eq 1 ]]
then

ifDev=$(echo ${line1} | grep "^dev=" | wc -l)
if [[ ${ifDev} -eq 1 ]]
then
DevName=$(echo ${line1} | sed 's/dev=//g')
count=$(echo ${count} + 1 | bc)
fi

ifNodeName=$(echo ${line1} | grep "^nodename=" | wc -l)
if [[ ${ifNodeName} -eq 1 ]]
then
NodeName=$(echo ${line1} | sed 's/nodename=//g')
count=$(echo ${count} + 1 | bc)
fi

fi

if [[ ${count} -eq 3 ]]
then
echo "${MountName} ${DevName} ${NodeName}"
FoundMount=0
count=0
NodeName=""
DevName=""
fi

done < /etc/filesystems | grep ${BACKUP_STORE_IP} | grep ${remote_name} | awk '{print $1}')

if [ -z "$RMANBACKUP_MOUNTPOINT" ];
then
export RMAN_SCRIPT_ERROR_MSG="Mount entry missing from /etc/filesystems"
export RMAN_SCRIPT_RESOLUTION_MSG="Add mount entry to /etc/filesystems"
echo "Entry for Phoenix Backup Store mount not found in /etc/filesystems... exiting"
exit 1
fi

remote_mnt=$(echo ${REMOTE_MOUNTPOINT} | sed 's/:/ /g')
ACTUAL_MOUNTPOINT=$(mount | grep "^$remote_mnt" | sed 's/\s\+/ /g' | cut -d " " -f3 2> /dev/null)

if [ -z "$ACTUAL_MOUNTPOINT" ];
then
mount "$RMANBACKUP_MOUNTPOINT" 2> /dev/null
if [ $? -ne 0 ];
then
export RMAN_SCRIPT_ERROR_MSG="Failed to mount backup store"
export RMAN_SCRIPT_RESOLUTION_MSG="Verify mount entry in /etc/filesystems"
echo "Unable to mount $RMANBACKUP_MOUNTPOINT... exiting"
exit 1
fi
else
RMANBACKUP_MOUNTPOINT=$ACTUAL_MOUNTPOINT
fi

export PATH=$ORACLE_HOME/bin:$PATH
full_backup () {

export RMAN_SCRIPT_STAGE="Create Full Backup Directory"
echo "Creating Dir $RMANBACKUP_MOUNTPOINT/$SID'/full'"

if [ ! -e "$RMANBACKUP_MOUNTPOINT/$SID/full" ]
then
mkdir -p "$RMANBACKUP_MOUNTPOINT/$SID/full"
if [ $? -eq 0 ];
then
echo "Created directory for full backup $RMANBACKUP_MOUNTPOINT/$SID/full"
else
export RMAN_SCRIPT_ERROR_MSG="Failed to create full backup directory"
export RMAN_SCRIPT_RESOLUTION_MSG="Check directory permissions and writability"
echo "Oracle user does not have permission for $RMANBACKUP_MOUNTPOINT directory... exiting"
exit 1
fi
elif [ ! -d "$RMANBACKUP_MOUNTPOINT/${SID}/full" ];
then
export RMAN_SCRIPT_ERROR_MSG="Path conflict: full path is a file, expected directory"
export RMAN_SCRIPT_RESOLUTION_MSG="Remove conflicting file and retry"
echo "$RMANBACKUP_MOUNTPOINT is not a directory... exiting"
exit 1
fi

# Creating Archivelog Directory
export RMAN_SCRIPT_STAGE="Create Archivelogs Backup Directory"
if [ ! -e "$RMANBACKUP_MOUNTPOINT/${SID}/archivelogs" ]
then
mkdir -p "$RMANBACKUP_MOUNTPOINT/${SID}/archivelogs"
if [ $? -eq 0 ];
then
echo "Created directory for archivelogs backup $RMANBACKUP_MOUNTPOINT/$SID/archivelogs"
else
export RMAN_SCRIPT_ERROR_MSG="Failed to create archivelogs directory"
export RMAN_SCRIPT_RESOLUTION_MSG="Check directory permissions and writability"
echo "Oracle user does not have permission for $RMANBACKUP_MOUNTPOINT directory... exiting"
exit 1
fi
elif [ ! -d "$RMANBACKUP_MOUNTPOINT/${SID}/archivelogs" ];
then
export RMAN_SCRIPT_ERROR_MSG="Path conflict: archivelogs path is a file, expected directory"
export RMAN_SCRIPT_RESOLUTION_MSG="Remove conflicting file and retry"
echo "$RMANBACKUP_MOUNTPOINT is not a directory... exiting"
exit 1
fi

LOG_FILE_DIR=$RMANBACKUP_MOUNTPOINT/'_workspace/RMAN_Logs'
echo "Creating Log File Dir: =$RMANBACKUP_MOUNTPOINT'/_workspace/RMAN_Logs'"

if [ ! -e "$LOG_FILE_DIR" ]
then
mkdir -p "$LOG_FILE_DIR"
if [ $? -eq 0 ];
then
echo "Created log directory for oracle backup $LOG_FILE_DIR"
else
export RMAN_SCRIPT_ERROR_MSG="Failed to create RMAN log directory"
export RMAN_SCRIPT_RESOLUTION_MSG="Check directory permissions and writability"
echo "Oracle user does not have permission for $LOG_FILE_DIR directory... exiting"
exit 1
fi
fi

RMANBACKUP_MOUNTPOINT_FULL=$RMANBACKUP_MOUNTPOINT/$SID

touch "$RMANBACKUP_MOUNTPOINT/_workspace/" 2>/dev/null
if [ $? -ne 0 ];
then
export RMAN_SCRIPT_ERROR_MSG="Failed to write to workspace folder"
export RMAN_SCRIPT_RESOLUTION_MSG="Check directory permissions and writability"
echo "$RMANBACKUP_MOUNTPOINT directory is not writable.. exiting"
exit 1
fi

# Checking if any .lock file is present and deleting the same if the PID is NOT running.
echo "Checking for backup lock file"
export RMAN_SCRIPT_STAGE="Check for Backup Lock File"
export BKP_CONTINUE=0
is_lock_file_present=$(find "${RMANBACKUP_MOUNTPOINT}" -type f -name ".RMAN_FULL_lock_*" | wc -l)
if [[ ${is_lock_file_present} -ne 0 ]]
then
for _lock_file in $(find "${RMANBACKUP_MOUNTPOINT}" -type f -name ".RMAN_FULL_lock_*" | xargs)
do
_pid=$(echo "${_lock_file}" | cut -d"_" -f4)
is_pid_proc_running=$(ps -ef | grep "${_pid}" | grep -v grep | wc -l)
if [[ ${is_pid_proc_running} -ne 0 ]]
then
echo "[INFO] Full backup Lock File: ${_lock_file} is present and PID is active"
export BKP_CONTINUE=1
else
echo "[INFO] Full backup Lock File: ${_lock_file} is present and PID is NOT active"
echo "Deleting ${_lock_file}"
rm "${_lock_file}"
if [ -e "${_lock_file}" ]
then
echo "ERROR deleting file ${_lock_file}"
export BKP_CONTINUE=1
fi
fi
done

if [[ ${BKP_CONTINUE} -eq 1 ]]
then
export RMAN_SCRIPT_ERROR_MSG="Skipping backup: active RMAN backup or lock file present"
export RMAN_SCRIPT_RESOLUTION_MSG="Wait for active backup to finish or remove stale lock file"
echo "Skipping backup: active RMAN backup or lock file present... exiting"
exit 1
fi
fi

# Creating a .lock file to represent current active full/diff backup.
export file_stamp=$(date | sed -e 's/ /_/g')
PID=$$
LOCK_FILE="${RMANBACKUP_MOUNTPOINT}/.RMAN_FULL_lock_${PID}_${file_stamp}"
echo -n > "${LOCK_FILE}"
if [ -e "${LOCK_FILE}" ]
then
echo "[INFO] Lock file created: ${LOCK_FILE}"
else
export RMAN_SCRIPT_ERROR_MSG="Failed to create backup lock file"
export RMAN_SCRIPT_RESOLUTION_MSG="Check backup mount disk space and permissions"
echo "Error creating lock file: ${LOCK_FILE}"
echo "[ERROR] Backup will now stop"
exit 1
fi

echo "Starting with RMAN backup"

export RMAN_SCRIPT_STAGE="Request RMAN Snapshot for Full Backup"
res_rmanbackup=$(curl -X POST http://$BACKUP_STORE_IP:9090/druva-phoenix/v1/mounts/$BACKUP_MOUNT/${SID}/full/rmanbackup 2> /dev/null)
if [ $? -ne 0 ];
then
export RMAN_SCRIPT_ERROR_MSG="Failed to request RMAN snapshot"
export RMAN_SCRIPT_RESOLUTION_MSG="Verify backup mount configuration"
echo "Request to start phoenix backup failed... exiting"
echo "Response from Phoenix Backup Store: "$res_rmanbackup
rm "${LOCK_FILE}"
exit 1
fi

echo "Response RMAN Backup: ${res_rmanbackup}"

SNAPSHOT_NAME=$(echo "$res_rmanbackup" | awk -F "snap_name" '{print $2}' | cut -d '"' -f3)
if [ -z "$SNAPSHOT_NAME" ];
then
export RMAN_SCRIPT_ERROR_MSG="Failed to get snapshot name"
export RMAN_SCRIPT_RESOLUTION_MSG="Verify backup mount configuration"
echo "Failed to get Snapshot name. Exiting. Please check Export Service Logs in PBS"
rm "${LOCK_FILE}"
exit 1
fi

echo "Snapshot to be created ${SNAPSHOT_NAME}"

export RMAN_SCRIPT_STAGE="Run RMAN Backup"
RMAN_LOGFILE=$LOG_FILE_DIR'/rman_full_backup_'${SNAPSHOT_NAME}_${ORACLE_SID}'.log'
echo -n > "$RMAN_LOGFILE"
echo "RMAN Logfile: ${RMAN_LOGFILE}"

rman log="$RMAN_LOGFILE" 2> /dev/null << EOF
connect target /
set echo on;

configure backup optimization on;
configure controlfile autobackup on;
configure device type disk parallelism $PARALLELISM BACKUP TYPE TO COPY;
configure datafile backup copies for device type disk to 1;
configure archivelog backup copies for device type disk to 1;
configure channel device type disk format '${RMANBACKUP_MOUNTPOINT_FULL}/full/datafile_%U.bkp';
configure controlfile autobackup format for device type disk to '${RMANBACKUP_MOUNTPOINT_FULL}/full/full_controlfile_%d_%F.bkp';

run
{
sql 'alter system archive log current';
backup incremental level 1 for recover of copy with tag 'phoenix_oracle_backup' database;
sql 'alter system archive log current';
backup as backupset format '${RMANBACKUP_MOUNTPOINT_FULL}/archivelogs/%d_%h_%e_%s_%t.arc' archivelog all not backed up;

#Force is to ignore I/O errors
delete noprompt obsolete device type disk;
delete force NOPROMPT expired copy;
delete force NOPROMPT expired backup;
#adding this command to delete backups older than 5 days
DELETE FORCE NOPROMPT BACKUP COMPLETED BEFORE 'sysdate-5';

crosscheck backup;
crosscheck copy;
}

configure backup optimization clear;
configure controlfile autobackup clear;
exit
EOF

RMAN_EXIT_STATUS=$?
if [ $RMAN_EXIT_STATUS -ne 0 ];
then
export RMAN_SCRIPT_ERROR_MSG="RMAN backup failed (exit_code: ${RMAN_EXIT_STATUS})"
export RMAN_SCRIPT_RESOLUTION_MSG="Check RMAN logs and fix the issue"
echo ""
echo "rman failed with status $RMAN_EXIT_STATUS.. exiting"
rm "${LOCK_FILE}"
if [ -e "${LOCK_FILE}" ]
then
echo "[ERROR] Could NOT delete Lock file: ${LOCK_FILE}"
else
dt=$(date | sed -e 's/ /_/g')
echo "[INFO] Lock file deleted: ${LOCK_FILE} at ${dt} "
fi
exit 1
fi

echo "RMAN log location: $LOG_FILE_DIR/rman_full_backup_${SNAPSHOT_NAME}_${ORACLE_SID}.log"

export RMAN_SCRIPT_STAGE="Upload RMAN Logs"
echo "Notifying Phoenix to upload RMAN Logs"

rman_uploadlog_res=$(curl -X POST -H "Content-Type: multipart/form-data" -F "file=@$LOG_FILE_DIR/rman_full_backup_${SNAPSHOT_NAME}_${ORACLE_SID}.log" -F mountpoint=$RMANBACKUP_MOUNTPOINT -F platform=aix http://$BACKUP_STORE_IP:9090/druva-phoenix/v1/mounts/$BACKUP_MOUNT/uploadlog 2> /dev/null)
if [ $? -ne 0 ];
then
echo "Request to send RMAN Logs failed..."
echo "Response from Phoenix Backup Store: "$rman_uploadlog_res
fi

rm "${LOCK_FILE}"
if [ -e "${LOCK_FILE}" ]
then
echo "[ERROR] Could NOT delete Lock file: ${LOCK_FILE}"
else
dt=$(date | sed -e 's/ /_/g')
echo "[INFO] Lock file deleted: ${LOCK_FILE} at ${dt} "
fi

export RMAN_SCRIPT_STAGE="End Backup"
echo "Notifying Phoenix to end backup"
final_res=$(curl -X PUT http://$BACKUP_STORE_IP:9090/druva-phoenix/v1/mounts/$BACKUP_MOUNT/backup 2> /dev/null)

if [ $? -ne 0 ];
then
export RMAN_SCRIPT_ERROR_MSG="Failed to end Phoenix Backup with response: $final_res"
export RMAN_SCRIPT_RESOLUTION_MSG="Verify export service is reachable and check its logs"
echo "Request to end phoenix backup failed... exiting"
echo "Response from Phoenix Backup Store: "$final_res

rm "${LOCK_FILE}" 2>/dev/null
if [ -e "${LOCK_FILE}" ]
then
echo "[ERROR] Could NOT delete Lock file: ${LOCK_FILE}"
else
dt=$(date | sed -e 's/ /_/g')
echo "[INFO] Lock file deleted: ${LOCK_FILE} at ${dt} "
fi
exit 1
fi

ERROR_CODE=$(echo "$final_res" | awk -F "error_code" '{print $2}' | cut -d ':' -f2 | cut -d ',' -f1)
if [ "$ERROR_CODE" -ne 0 ];
then
export RMAN_SCRIPT_ERROR_MSG="Failed to end Phoenix Backup (error_code: ${ERROR_CODE})"
export RMAN_SCRIPT_RESOLUTION_MSG="Verify export service is reachable and check its logs"
echo "Response from Phoenix Backup Store: "$final_res
echo "Request to End Phoenix backup failed... exiting"
exit 1
fi
echo "$final_res"

echo "Exiting with successful status"
}

# Main
full_backup

Did this answer your question?