intial commit
This commit is contained in:
32
list_mv.sh
Executable file
32
list_mv.sh
Executable file
@@ -0,0 +1,32 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# List MVs using API call to CDM, for diagnostic purposes
|
||||||
|
# Written for Avon
|
||||||
|
# v1.1 - James Pattinson - October 2023
|
||||||
|
#
|
||||||
|
# usage: list_mv.sh
|
||||||
|
|
||||||
|
|
||||||
|
MYDIR="$(dirname "$(readlink -f "$0")")"
|
||||||
|
source $MYDIR/rbk_api.conf
|
||||||
|
source $MYDIR/oracle_funcs.sh
|
||||||
|
|
||||||
|
# Script starts here
|
||||||
|
|
||||||
|
echo Service account in use is $ID
|
||||||
|
|
||||||
|
echo ALL MVs
|
||||||
|
|
||||||
|
ENDPOINT="https://$RUBRIK_IP/api/internal/managed_volume"
|
||||||
|
rest_api_get
|
||||||
|
|
||||||
|
grep -Eo '"name"[^,]*' /tmp/rbkresponse.$$
|
||||||
|
|
||||||
|
echo NonRelic MVs
|
||||||
|
|
||||||
|
ENDPOINT="https://$RUBRIK_IP/api/internal/managed_volume?is_relic=false"
|
||||||
|
rest_api_get
|
||||||
|
|
||||||
|
grep -Eo '"name"[^,]*' /tmp/rbkresponse.$$
|
||||||
|
|
||||||
|
cleanup
|
||||||
304
oracle_funcs.sh
Executable file
304
oracle_funcs.sh
Executable file
@@ -0,0 +1,304 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Oracle shell script support functions
|
||||||
|
# Written for Avon
|
||||||
|
# v1.0 - James Pattinson - October 2023
|
||||||
|
|
||||||
|
nowait=0
|
||||||
|
|
||||||
|
LOGFILE=$API_LOG_DIR/api_calls.log
|
||||||
|
mkdir -p $API_LOG_DIR
|
||||||
|
tabwidth=25
|
||||||
|
|
||||||
|
HOST=$(hostname -s)
|
||||||
|
|
||||||
|
os=$(uname -o)
|
||||||
|
if [ $os == "Solaris" ]; then
|
||||||
|
# Use the GNU version of date binary
|
||||||
|
DATE=/usr/gnu/bin/date
|
||||||
|
else
|
||||||
|
DATE=$(which date)
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "`$DATE` -$$-: CALLED $0 $@" >> $LOGFILE
|
||||||
|
|
||||||
|
trap ctrl_c INT
|
||||||
|
|
||||||
|
function ctrl_c () {
|
||||||
|
echo "`$DATE` -$$-: TRAPPED CTRL-C - EXITING" >> $LOGFILE
|
||||||
|
exit_with_error
|
||||||
|
}
|
||||||
|
|
||||||
|
function ctrl_c_inhibit () {
|
||||||
|
echo "`$DATE` -$$-: TRAPPED CTRL-C - CONTINUING" >> $LOGFILE
|
||||||
|
}
|
||||||
|
|
||||||
|
exit_with_error () {
|
||||||
|
# if [ $usingsatoken ]; then
|
||||||
|
# ENDPOINT="https://$RUBRIK_IP/api/v1/session/me"
|
||||||
|
# rest_api_delete
|
||||||
|
# check_http_error
|
||||||
|
# fi
|
||||||
|
|
||||||
|
cat /tmp/rbkresponse.$$ | mailx -s "Backup error on ${HOST} for ${ORACLE_SID}. Please investigate" $ALERT_EMAILS
|
||||||
|
rm -f /tmp/rbkresponse.$$
|
||||||
|
rm -f /tmp/mountedDBs.$$
|
||||||
|
rm -f $PIDFILE
|
||||||
|
echo Aborting Script!
|
||||||
|
echo "`$DATE` -$$-: EXITED WITH ERROR $0 $@" >> $LOGFILE
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
check_http_error () {
|
||||||
|
# All good responses start with a 2
|
||||||
|
if [ ${http_response:0:1} != "2" ]; then
|
||||||
|
echo FATAL: HTTP error from API call: $http_response. The server responded with:
|
||||||
|
cat /tmp/rbkresponse.$$ ; echo ; exit_with_error
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_pid () {
|
||||||
|
|
||||||
|
if [ -f $PIDFILE ]
|
||||||
|
then
|
||||||
|
PID=$(cat $PIDFILE)
|
||||||
|
ps -p $PID > /dev/null 2>&1
|
||||||
|
if [ $? -eq 0 ]
|
||||||
|
then
|
||||||
|
echo "ERROR: MV already being used by process ID $PID"
|
||||||
|
ps -fp $PID
|
||||||
|
exit_with_error
|
||||||
|
else
|
||||||
|
## Process not found assume not running
|
||||||
|
echo $$ > $PIDFILE
|
||||||
|
if [ $? -ne 0 ]
|
||||||
|
then
|
||||||
|
echo "ERROR: Could not create mvLock file"
|
||||||
|
exit_with_error
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo $$ > $PIDFILE
|
||||||
|
if [ $? -ne 0 ]
|
||||||
|
then
|
||||||
|
echo "ERROR: Could not create mvLock file"
|
||||||
|
exit_with_error
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
check_get_token () {
|
||||||
|
|
||||||
|
if [ -z "${AUTH_TOKEN}" ]; then
|
||||||
|
|
||||||
|
# RSC
|
||||||
|
id_string=$(echo $ID | cut -d\| -f 2)
|
||||||
|
# CDM
|
||||||
|
id_string=$(echo $ID | cut -d: -f 4)
|
||||||
|
|
||||||
|
if [ -f ~/.rbksession.$id_string ]; then
|
||||||
|
echo "`$DATE` -$$-: AUTH SESSION FILE EXISTS" >> $LOGFILE
|
||||||
|
read expiration token < <(echo $(cat ~/.rbksession.$id_string))
|
||||||
|
if [ $($DATE +%s -u -d $expiration) -lt $(( $($DATE +%s) + 1800 )) ]; then
|
||||||
|
echo "`$DATE` -$$-: AUTH TOKEN EXPIRED" >> $LOGFILE
|
||||||
|
get_token
|
||||||
|
else
|
||||||
|
AUTH_TOKEN=$token
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
get_token
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
get_token () {
|
||||||
|
|
||||||
|
trap '' INT
|
||||||
|
echo "`$DATE` -$$-: AUTH USER $ID" >> $LOGFILE
|
||||||
|
MYENDPOINT="https://$RUBRIK_IP/api/v1/service_account/session"
|
||||||
|
MYPAYLOAD="{\"serviceAccountId\":\"$ID\",\"secret\":\"$SECRET\"}"
|
||||||
|
|
||||||
|
http_response=$(curl -s -k -o /tmp/rbkresponse.$$ -w "%{http_code}" -X POST $MYENDPOINT -H "accept: application/json" -H "Content-Type: application/json" -d $MYPAYLOAD)
|
||||||
|
check_http_error
|
||||||
|
|
||||||
|
AUTH_TOKEN=$(grep -Eo '"token"[^,]*' /tmp/rbkresponse.$$ | grep -Eo '[^:]*$' | sed 's/\"//g')
|
||||||
|
SESSION=$(grep -Eo '"sessionId"[^,]*' /tmp/rbkresponse.$$ | grep -Eo '[^:]*$' | sed 's/\"//g')
|
||||||
|
EXPIRATION=$(grep -Eo '"expirationTime"[^,]*' /tmp/rbkresponse.$$ | cut -d: -f 2-4 | sed 's/\"//g' | sed 's/.000Z//;s/T/Z/')
|
||||||
|
|
||||||
|
echo "`$DATE` -$$-: AUTH SESSION $SESSION" >> $LOGFILE
|
||||||
|
echo "`$DATE` -$$-: SAVING TOKEN TO FILE" >> $LOGFILE
|
||||||
|
echo "$EXPIRATION $AUTH_TOKEN" > ~/.rbksession.$id_string
|
||||||
|
usingsatoken=1
|
||||||
|
trap ctrl_c INT
|
||||||
|
}
|
||||||
|
|
||||||
|
# HTTP GET: Given $ENDPOINT write output to file
|
||||||
|
rest_api_get () {
|
||||||
|
check_get_token
|
||||||
|
http_response=$(curl -s -k -o /tmp/rbkresponse.$$ -w "%{http_code}" -X GET $ENDPOINT -H "accept: application/json" -H "Authorization: Bearer $AUTH_TOKEN")
|
||||||
|
echo "`$DATE` -$$-: REST API GET: ENDPOINT $ENDPOINT" >> $LOGFILE
|
||||||
|
echo "`$DATE` -$$-: REST API GET: RESPONSE STARTS" >> $LOGFILE
|
||||||
|
cat /tmp/rbkresponse.$$ >> $LOGFILE
|
||||||
|
echo >> $LOGFILE
|
||||||
|
echo "`$DATE` -$$-: REST API GET: RESPONSE ENDS" >> $LOGFILE
|
||||||
|
check_http_error
|
||||||
|
}
|
||||||
|
|
||||||
|
rest_api_get_2 () {
|
||||||
|
check_get_token
|
||||||
|
http_response=$(curl -s -k -o /tmp/rbkresponse2.$$ -w "%{http_code}" -X GET $ENDPOINT -H "accept: application/json" -H "Authorization: Bearer $AUTH_TOKEN")
|
||||||
|
echo "`$DATE` -$$-: REST API GET: ENDPOINT $ENDPOINT" >> $LOGFILE
|
||||||
|
echo "`$DATE` -$$-: REST API GET: RESPONSE STARTS" >> $LOGFILE
|
||||||
|
cat /tmp/rbkresponse2.$$ >> $LOGFILE
|
||||||
|
echo >> $LOGFILE
|
||||||
|
echo "`$DATE` -$$-: REST API GET: RESPONSE ENDS" >> $LOGFILE
|
||||||
|
check_http_error
|
||||||
|
}
|
||||||
|
|
||||||
|
# HTTP POST: Given $ENDPOINT and $PAYLOAD write output to file
|
||||||
|
rest_api_post () {
|
||||||
|
check_get_token
|
||||||
|
http_response=$(curl -s -k -o /tmp/rbkresponse.$$ -w "%{http_code}" -X POST $ENDPOINT -H "accept: application/json" -H "Authorization: Bearer $AUTH_TOKEN" -H "Content-Type: application/json" -d $PAYLOAD)
|
||||||
|
echo "`$DATE` -$$-: REST API POST: ENDPOINT $ENDPOINT" >> $LOGFILE
|
||||||
|
echo "`$DATE` -$$-: REST API POST: PAYLOAD $PAYLOAD" >> $LOGFILE
|
||||||
|
echo "`$DATE` -$$-: REST API POST: RESPONSE STARTS" >> $LOGFILE
|
||||||
|
cat /tmp/rbkresponse.$$ >> $LOGFILE
|
||||||
|
echo >> $LOGFILE
|
||||||
|
echo "`$DATE` -$$-: REST API POST: RESPONSE ENDS" >> $LOGFILE
|
||||||
|
check_http_error
|
||||||
|
}
|
||||||
|
|
||||||
|
rest_api_post_empty () {
|
||||||
|
check_get_token
|
||||||
|
http_response=$(curl -s -k -o /tmp/rbkresponse.$$ -w "%{http_code}" -X POST $ENDPOINT -H "accept: application/json" -H "Authorization: Bearer $AUTH_TOKEN" -H "Content-Type: application/json")
|
||||||
|
echo "`$DATE` -$$-: REST API POST: ENDPOINT $ENDPOINT" >> $LOGFILE
|
||||||
|
echo "`$DATE` -$$-: REST API POST: PAYLOAD <NULL>" >> $LOGFILE
|
||||||
|
echo "`$DATE` -$$-: REST API POST: RESPONSE STARTS" >> $LOGFILE
|
||||||
|
cat /tmp/rbkresponse.$$ >> $LOGFILE
|
||||||
|
echo >> $LOGFILE
|
||||||
|
echo "`$DATE` -$$-: REST API POST: RESPONSE ENDS" >> $LOGFILE
|
||||||
|
check_http_error
|
||||||
|
}
|
||||||
|
|
||||||
|
rest_api_patch () {
|
||||||
|
check_get_token
|
||||||
|
http_response=$(curl -s -k -o /tmp/rbkresponse.$$ -w "%{http_code}" -X PATCH $ENDPOINT -H "accept: application/json" -H "Authorization: Bearer $AUTH_TOKEN" -H "Content-Type: application/json" -d "$PAYLOAD")
|
||||||
|
echo "`$DATE` -$$-: REST API PATCH: ENDPOINT $ENDPOINT" >> $LOGFILE
|
||||||
|
echo "`$DATE` -$$-: REST API PATCH: PAYLOAD $PAYLOAD" >> $LOGFILE
|
||||||
|
echo "`$DATE` -$$-: REST API PATCH: RESPONSE STARTS" >> $LOGFILE
|
||||||
|
cat /tmp/rbkresponse.$$ >> $LOGFILE
|
||||||
|
echo >> $LOGFILE
|
||||||
|
echo "`$DATE` -$$-: REST API PATCH: RESPONSE ENDS" >> $LOGFILE
|
||||||
|
check_http_error
|
||||||
|
}
|
||||||
|
|
||||||
|
rest_api_delete () {
|
||||||
|
check_get_token
|
||||||
|
http_response=$(curl -s -k -o /tmp/rbkresponse.$$ -w "%{http_code}" -X DELETE $ENDPOINT -H "accept: application/json" -H "Authorization: Bearer $AUTH_TOKEN")
|
||||||
|
echo "`$DATE` -$$-: REST API DELETE: $http_response: ENDPOINT $ENDPOINT" >> $LOGFILE
|
||||||
|
check_http_error
|
||||||
|
}
|
||||||
|
|
||||||
|
get_mv () {
|
||||||
|
|
||||||
|
ENDPOINT="https://$RUBRIK_IP/api/internal/managed_volume?name=$mv_name&is_relic=false"
|
||||||
|
rest_api_get
|
||||||
|
|
||||||
|
mvId=$(grep -Eo '"id"[^,]*' /tmp/rbkresponse.$$ | grep -Eo 'ManagedVolume:::[a-z0-9-]*')
|
||||||
|
numChannels=$(grep -Eo '"numChannels"[^,]*' /tmp/rbkresponse.$$ | cut -d: -f2)
|
||||||
|
|
||||||
|
if [[ $mvId == "" ]]; then
|
||||||
|
echo ERROR: MV with name $mv_name was not found
|
||||||
|
exit_with_error
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
get_data_mv () {
|
||||||
|
|
||||||
|
mv_name=${HOST}_${ORACLE_SID}_data
|
||||||
|
|
||||||
|
ENDPOINT="https://$RUBRIK_IP/api/internal/managed_volume?name=$mv_name&is_relic=false"
|
||||||
|
rest_api_get
|
||||||
|
|
||||||
|
mvId=$(grep -Eo '"id"[^,]*' /tmp/rbkresponse.$$ | grep -Eo 'ManagedVolume:::[a-z0-9-]*')
|
||||||
|
numChannels=$(grep -Eo '"numChannels"[^,]*' /tmp/rbkresponse.$$ | cut -d: -f2)
|
||||||
|
|
||||||
|
if [[ $mvId == "" ]]; then
|
||||||
|
echo ERROR: MV with name $mv_name was not found
|
||||||
|
exit_with_error
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
get_log_mv () {
|
||||||
|
|
||||||
|
# Look for a log volume. If not present, return the data volume
|
||||||
|
|
||||||
|
mv_name=${HOST}_${ORACLE_SID}_log
|
||||||
|
ENDPOINT="https://$RUBRIK_IP/api/internal/managed_volume?name=$mv_name&is_relic=false"
|
||||||
|
rest_api_get
|
||||||
|
|
||||||
|
logMvId=$(grep -Eo '"id"[^,]*' /tmp/rbkresponse.$$ | grep -Eo 'ManagedVolume:::[a-z0-9-]*')
|
||||||
|
|
||||||
|
if [[ $logMvId == "" ]]; then
|
||||||
|
echo "INFO: Log volume ($mv_name) not found. Logs will be written to DB volume"
|
||||||
|
logMvPresent=0
|
||||||
|
mv_name=${HOST}_${ORACLE_SID}_data
|
||||||
|
|
||||||
|
ENDPOINT="https://$RUBRIK_IP/api/internal/managed_volume?name=$mv_name&is_relic=false"
|
||||||
|
rest_api_get
|
||||||
|
|
||||||
|
mvId=$(grep -Eo '"id"[^,]*' /tmp/rbkresponse.$$ | grep -Eo 'ManagedVolume:::[a-z0-9-]*')
|
||||||
|
numChannels=$(grep -Eo '"numChannels"[^,]*' /tmp/rbkresponse.$$ | cut -d: -f2)
|
||||||
|
|
||||||
|
if [[ $mvId == "" ]]; then
|
||||||
|
echo ERROR: MV with name $mv_name was not found
|
||||||
|
exit_with_error
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
mvId=$(grep -Eo '"id"[^,]*' /tmp/rbkresponse.$$ | grep -Eo 'ManagedVolume:::[a-z0-9-]*')
|
||||||
|
numChannels=$(grep -Eo '"numChannels"[^,]*' /tmp/rbkresponse.$$ | cut -d: -f2)
|
||||||
|
logMvPresent=1
|
||||||
|
echo "INFO: Log volume ($mv_name) exists with $numChannels channels"
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
open_mv () {
|
||||||
|
|
||||||
|
PIDFILE=/tmp/mvLock_${mv_name}.pid
|
||||||
|
check_pid
|
||||||
|
ENDPOINT="https://$RUBRIK_IP/api/internal/managed_volume/$mvId/begin_snapshot"
|
||||||
|
echo "Opening MV $mv_name with ID $mvId (numChannels is $numChannels)"
|
||||||
|
rest_api_post_empty
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
close_mv () {
|
||||||
|
|
||||||
|
if [ -z "${SLANAME}" ]; then
|
||||||
|
echo Closing MV $mv_name using default assigned SLA
|
||||||
|
ENDPOINT="https://$RUBRIK_IP/api/internal/managed_volume/$mvId/end_snapshot"
|
||||||
|
rest_api_post_empty
|
||||||
|
else
|
||||||
|
get_sla
|
||||||
|
echo Closing MV $mv_name as On Demand with SLA $SLANAME
|
||||||
|
ENDPOINT="https://$RUBRIK_IP/api/internal/managed_volume/$mvId/end_snapshot"
|
||||||
|
PAYLOAD="{\"retentionConfig\":{\"slaId\":\"$slaId\"}}"
|
||||||
|
rest_api_post
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup () {
|
||||||
|
# if [ $usingsatoken ]; then
|
||||||
|
# ENDPOINT="https://$RUBRIK_IP/api/v1/session/me"
|
||||||
|
# rest_api_delete
|
||||||
|
# fi
|
||||||
|
echo "`$DATE` -$$-: EXITED $0 $@" >> $LOGFILE
|
||||||
|
rm -f /tmp/mountedDBs.$$
|
||||||
|
rm -f /tmp/rbkresponse.$$
|
||||||
|
rm -f $PIDFILE
|
||||||
|
}
|
||||||
26
rbk_api.conf.example
Executable file
26
rbk_api.conf.example
Executable file
@@ -0,0 +1,26 @@
|
|||||||
|
# ID and Key for RSC Service Account (starts with client|) (use single quotes)
|
||||||
|
ID='client|xxxxxxxxxxxxxxxxxxx'
|
||||||
|
SECRET=xxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
|
|
||||||
|
# DNS name of Rubrik CDM
|
||||||
|
RUBRIK_IP=<CDM address>
|
||||||
|
|
||||||
|
# Oracle Settings
|
||||||
|
MOUNTPOINT_PREFIX=/rubrik_
|
||||||
|
# How many hours of archivelog to keep on host. 0 means do not purge logs
|
||||||
|
HOSTLOGRET=2
|
||||||
|
|
||||||
|
# Percentage threshold to warn if an MV filesystem is getting full
|
||||||
|
MV_SPACE_WARN=75
|
||||||
|
|
||||||
|
# Logging directories
|
||||||
|
|
||||||
|
# API calls
|
||||||
|
API_LOG_DIR=/tmp/rubrik
|
||||||
|
# RMAN sessions
|
||||||
|
RMAN_LOG_DIR=/tmp/rubrik/rman
|
||||||
|
|
||||||
|
# List of email addresses to send failure alerts to
|
||||||
|
ALERT_EMAILS=root,oracle
|
||||||
|
# Set to 1 to enable email alert on success also
|
||||||
|
EMAIL_SUCCESS=1
|
||||||
121
rman_db.sh
Executable file
121
rman_db.sh
Executable file
@@ -0,0 +1,121 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# RMAN DB backup with incremental Merge
|
||||||
|
# Written for Avon
|
||||||
|
# v1.0 - James Pattinson - October 2023
|
||||||
|
#
|
||||||
|
# usage: rman_db.sh <ORACLE_SID>
|
||||||
|
|
||||||
|
MYDIR="$(dirname "$(readlink -f "$0")")"
|
||||||
|
|
||||||
|
export ORACLE_SID=$1
|
||||||
|
|
||||||
|
. $HOME/.profile
|
||||||
|
|
||||||
|
export ORAENV_ASK=NO
|
||||||
|
export ORACLE_SID=$1
|
||||||
|
|
||||||
|
. oraenv
|
||||||
|
|
||||||
|
export ORAENV_ASK=YES
|
||||||
|
|
||||||
|
source $MYDIR/rbk_api.conf
|
||||||
|
source $MYDIR/oracle_funcs.sh
|
||||||
|
|
||||||
|
#ORACLE_SID=$1
|
||||||
|
|
||||||
|
usage() { echo "Usage: $0 <DBNAME>]" 1>&2; exit 1; }
|
||||||
|
|
||||||
|
if [ -z "${ORACLE_SID}" ]; then
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
#ORAENV_ASK=NO
|
||||||
|
#. oraenv
|
||||||
|
|
||||||
|
export NLS_DATE_FORMAT='mm-dd-yyyy hh24:mi:ss'
|
||||||
|
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
|
||||||
|
|
||||||
|
MOUNTPOINT=$MOUNTPOINT_PREFIX$ORACLE_SID
|
||||||
|
|
||||||
|
mkdir -p $RMAN_LOG_DIR/$ORACLE_SID/
|
||||||
|
RMAN_LOG=$RMAN_LOG_DIR/$ORACLE_SID/rman_${ORACLE_SID}_DB_$(date +%d%m%y).log
|
||||||
|
|
||||||
|
# Disk space check
|
||||||
|
dusage=$(df -Ph | grep -E "$MOUNTPOINT" | sed s/%//g | awk -v spaceWarn=$MV_SPACE_WARN '{ if($5 >= spaceWarn) print $0;}')
|
||||||
|
if [ "$dusage" != "" ]; then
|
||||||
|
echo "WARNING: Disk Space Alert - sending email"
|
||||||
|
echo "$dusage" | mailx -s "WARNING: Rubrik MV Disk Space Alert On $(hostname) at $(date)" $ALERT_EMAILS
|
||||||
|
else
|
||||||
|
echo "INFO: Rubrik MV Disk usage is under threshold of ${MV_SPACE_WARN}%"
|
||||||
|
fi
|
||||||
|
|
||||||
|
get_data_mv
|
||||||
|
open_mv
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo ERROR: Unable to open MV, aborting
|
||||||
|
exit_with_error
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
echo Running RMAN with log to $RMAN_LOG
|
||||||
|
|
||||||
|
if [[ $numChannels -eq 1 ]]; then
|
||||||
|
allocate="allocate channel 'ch1' device type disk format '$MOUNTPOINT/%U';"
|
||||||
|
release="release channel ch1;"
|
||||||
|
channel0="$MOUNTPOINT"
|
||||||
|
else
|
||||||
|
|
||||||
|
for i in $(seq 0 $(($numChannels - 1))); do
|
||||||
|
allocate+="allocate channel 'c$i' device type disk format '$MOUNTPOINT/c$i/%U';"
|
||||||
|
release+="release channel c$i;"
|
||||||
|
done
|
||||||
|
channel0="$MOUNTPOINT/c0"
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Save the current time (minus one hour) to ensure we catch all archive logs
|
||||||
|
startTime=$(date +%m-%d-%Y\ %H:%M:%S -d '-1 hour')
|
||||||
|
|
||||||
|
# RMAN Part Here
|
||||||
|
###############################################################################
|
||||||
|
#cat > /tmp/rman.cmd <<EOF
|
||||||
|
|
||||||
|
# Now perform the backup and merge
|
||||||
|
rman nocatalog log $RMAN_LOG append > /dev/null <<EOF
|
||||||
|
connect target /
|
||||||
|
set echo on;
|
||||||
|
configure retention policy to recovery window of 1 days;
|
||||||
|
run {
|
||||||
|
set controlfile autobackup format for device type disk to '$channel0/cf_%F';
|
||||||
|
$allocate
|
||||||
|
backup incremental level 1 for recover of copy with tag 'rubrik_snap' database;
|
||||||
|
recover copy of database with tag 'rubrik_snap';
|
||||||
|
backup as copy current controlfile;
|
||||||
|
backup archivelog from time '$startTime' tag 'rubrik_snap_logs';
|
||||||
|
$release
|
||||||
|
}
|
||||||
|
allocate channel for maintenance device type disk;
|
||||||
|
crosscheck backup;
|
||||||
|
crosscheck copy;
|
||||||
|
delete noprompt obsolete device type disk;
|
||||||
|
delete noprompt backup of archivelog all completed before 'sysdate-3' tag rubrik_snap_logs;
|
||||||
|
release channel;
|
||||||
|
EOF
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
rmanStatus=$?
|
||||||
|
|
||||||
|
if [ $rmanStatus -ne 0 ]; then
|
||||||
|
echo "WARNING: RMAN DB backup exited with Non-zero status $rmanStatus. Emailing log"
|
||||||
|
cat $RMAN_LOG | mailx -s "RMAN Log backup Failed on ${HOST} for ${ORACLE_SID}" $ALERT_EMAILS
|
||||||
|
elif [ $EMAIL_SUCCESS -eq 1 ]; then
|
||||||
|
echo "SUCCESS: RMAN DB backup exited with zero status"
|
||||||
|
echo "RMAN job finished with Zero status. Note that this does not guarantee the contents of the backup." | mailx -s "SUCCESS: RMAN DB backup exited with zero status on ${HOST} for ${ORACLE_SID}" $ALERT_EMAILS
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Change permission of backup files to enable alternate host restore
|
||||||
|
find $MOUNTPOINT -type f -exec chmod 644 -- {} + 2>/dev/null
|
||||||
|
|
||||||
|
close_mv
|
||||||
136
rman_logs.sh
Executable file
136
rman_logs.sh
Executable file
@@ -0,0 +1,136 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# RMAN Log backup
|
||||||
|
# Written for Avon
|
||||||
|
# v1.1 - James Pattinson - October 2023
|
||||||
|
#
|
||||||
|
# usage: rman_logs.sh <ORACLE_SID>
|
||||||
|
|
||||||
|
MYDIR="$(dirname "$(readlink -f "$0")")"
|
||||||
|
export ORACLE_SID=$1
|
||||||
|
|
||||||
|
. $HOME/.profile
|
||||||
|
|
||||||
|
export ORAENV_ASK=NO
|
||||||
|
export ORACLE_SID=$1
|
||||||
|
|
||||||
|
. oraenv
|
||||||
|
|
||||||
|
export ORAENV_ASK=YES
|
||||||
|
|
||||||
|
source $MYDIR/rbk_api.conf
|
||||||
|
source $MYDIR/oracle_funcs.sh
|
||||||
|
|
||||||
|
#ORACLE_SID=$1
|
||||||
|
|
||||||
|
usage() { echo "Usage: $0 <DBNAME>]" 1>&2; exit 1; }
|
||||||
|
|
||||||
|
if [ -z "${ORACLE_SID}" ]; then
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
#ORAENV_ASK=NO
|
||||||
|
#. oraenv
|
||||||
|
|
||||||
|
export NLS_DATE_FORMAT='mm-dd-yyyy hh24:mi:ss'
|
||||||
|
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
|
||||||
|
|
||||||
|
mkdir -p $RMAN_LOG_DIR/$ORACLE_SID/
|
||||||
|
RMAN_LOG=$RMAN_LOG_DIR/$ORACLE_SID/rman_${ORACLE_SID}_LOG_$(date +%d%m%y).log
|
||||||
|
|
||||||
|
get_log_mv
|
||||||
|
open_mv
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo ERROR: Unable to open MV, aborting
|
||||||
|
exit_with_error
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $logMvPresent -eq 1 ]] && [[ $numChannels -eq 1 ]] ; then
|
||||||
|
MOUNTPOINT=$MOUNTPOINT_PREFIX${ORACLE_SID}_log
|
||||||
|
else
|
||||||
|
MOUNTPOINT=$MOUNTPOINT_PREFIX$ORACLE_SID
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Disk space check
|
||||||
|
dusage=$(df -Ph | grep -E "$MOUNTPOINT" | sed s/%//g | awk -v spaceWarn=$MV_SPACE_WARN '{ if($5 >= spaceWarn) print $0;}')
|
||||||
|
if [ "$dusage" != "" ]; then
|
||||||
|
echo "WARNING: Disk Space Alert - sending email"
|
||||||
|
echo "$dusage" | mailx -s "WARNING: Rubrik MV Disk Space Alert On $(hostname) at $(date)" $ALERT_EMAILS
|
||||||
|
else
|
||||||
|
echo "INFO: Rubrik MV Disk usage is under threshold of ${MV_SPACE_WARN}%"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo Running RMAN with log to $RMAN_LOG
|
||||||
|
|
||||||
|
if [[ $numChannels -eq 1 ]]; then
|
||||||
|
allocate="allocate channel 'ch1' device type disk format '$MOUNTPOINT/%U';"
|
||||||
|
release="release channel ch1;"
|
||||||
|
channel0="$MOUNTPOINT"
|
||||||
|
else
|
||||||
|
|
||||||
|
for i in $(seq 0 $(($numChannels - 1))); do
|
||||||
|
allocate+="allocate channel 'c$i' device type disk format '$MOUNTPOINT/log_c$i/%U';"
|
||||||
|
release+="release channel c$i;"
|
||||||
|
done
|
||||||
|
channel0="$MOUNTPOINT/log_c0"
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# RMAN Part Here
|
||||||
|
###############################################################################
|
||||||
|
rman nocatalog log $RMAN_LOG append > /dev/null <<EOF
|
||||||
|
connect target /
|
||||||
|
set echo on;
|
||||||
|
show all;
|
||||||
|
crosscheck backup;
|
||||||
|
run {
|
||||||
|
set controlfile autobackup format for device type disk to '$channel0/cf_%F';
|
||||||
|
$allocate
|
||||||
|
backup archivelog all not backed up 1 times tag 'RUBRIK_LOGS';
|
||||||
|
$release
|
||||||
|
}
|
||||||
|
allocate channel for maintenance device type disk;
|
||||||
|
delete noprompt backup of archivelog all completed before 'sysdate-3' tag RUBRIK_LOGS;
|
||||||
|
release channel;
|
||||||
|
EOF
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
rmanStatus=$?
|
||||||
|
|
||||||
|
if [ $rmanStatus -ne 0 ]; then
|
||||||
|
echo "WARNING: RMAN Log backup exited with Non-zero status $rmanStatus. Emailing log"
|
||||||
|
cat $RMAN_LOG | mailx -s "RMAN Log backup Failed on ${HOST} for ${ORACLE_SID}" $ALERT_EMAILS
|
||||||
|
elif [ $EMAIL_SUCCESS -eq 1 ]; then
|
||||||
|
echo "SUCCESS: RMAN Log backup exited with zero status"
|
||||||
|
echo "RMAN job finished with Zero status. Note that this does not guarantee the contents of the backup." | mailx -s "SUCCESS: RMAN Log backup exited with zero status on ${HOST} for ${ORACLE_SID}" $ALERT_EMAILS
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Change permission of backup files to enable alternate host restore
|
||||||
|
find $MOUNTPOINT -type f -exec chmod 644 -- {} + 2>/dev/null
|
||||||
|
|
||||||
|
close_mv
|
||||||
|
|
||||||
|
if [[ $HOSTLOGRET -gt 0 ]]; then
|
||||||
|
|
||||||
|
echo "Starting post-backup RMAN log purge"
|
||||||
|
|
||||||
|
# Remove archivelogs from host after backup
|
||||||
|
###############################################################################
|
||||||
|
rman nocatalog log $RMAN_LOG append > /dev/null <<EOF
|
||||||
|
connect target /
|
||||||
|
set echo on;
|
||||||
|
run {
|
||||||
|
delete noprompt archivelog until time 'sysdate-$HOSTLOGRET/24' backed up 1 times to device type disk;
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
rmanStatus=$?
|
||||||
|
|
||||||
|
if [ $rmanStatus -ne 0 ]; then
|
||||||
|
echo "WARNING: RMAN purge exited with Non-zero status $rmanStatus. Emailing log"
|
||||||
|
cat $RMAN_LOG | mailx -s "RMAN purge on ${HOST} for ${ORACLE_SID} " $ALERT_EMAILS
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
54
rubrik_mv_op.sh
Executable file
54
rubrik_mv_op.sh
Executable file
@@ -0,0 +1,54 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Open and Close MV using API call to CDM
|
||||||
|
# Written for Avon
|
||||||
|
# v1.0 - James Pattinson - October 2023
|
||||||
|
#
|
||||||
|
# usage: rubrik_mv_op.sh -d <DBNAME> -v <logs|data> -o <open|close>
|
||||||
|
#
|
||||||
|
# -d Oracle DBNAME
|
||||||
|
# -v Volume to operate on, logs or data
|
||||||
|
# -o Operation to perform - open or close the MV
|
||||||
|
|
||||||
|
MYDIR="$(dirname "$(readlink -f "$0")")"
|
||||||
|
source $MYDIR/rbk_api.conf
|
||||||
|
source $MYDIR/oracle_funcs.sh
|
||||||
|
|
||||||
|
usage() { echo "Usage: $0 -d <DBNAME> -v <logs|data> -o <open|close>" 1>&2; exit 1; }
|
||||||
|
|
||||||
|
force=0
|
||||||
|
|
||||||
|
while getopts "d:v:o:" o; do
|
||||||
|
case "${o}" in
|
||||||
|
d)
|
||||||
|
DBNAME=${OPTARG}
|
||||||
|
;;
|
||||||
|
v)
|
||||||
|
VOLUME=${OPTARG}
|
||||||
|
;;
|
||||||
|
o)
|
||||||
|
OPCODE=${OPTARG}
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
shift $((OPTIND-1))
|
||||||
|
|
||||||
|
if [ -z "${DBNAME}" ] || [ -z "${VOLUME}" ] || [ -z "${OPCODE}" ]; then
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Script starts here
|
||||||
|
|
||||||
|
mv_name=$(hostname -s)_${DBNAME}_${VOLUME}
|
||||||
|
get_mv
|
||||||
|
|
||||||
|
case $OPCODE in
|
||||||
|
open) open_mv ;;
|
||||||
|
close) close_mv ;;
|
||||||
|
*) echo "ERROR: Invalid opcode. Specify open or close" ; exit_with_error
|
||||||
|
esac
|
||||||
|
|
||||||
|
cleanup
|
||||||
Reference in New Issue
Block a user