From 6c1f8c926eef52dd29265492e3915cb386d67e91 Mon Sep 17 00:00:00 2001 From: James Pattinson Date: Tue, 28 Oct 2025 11:02:06 -0400 Subject: [PATCH] HP/UX fixes --- README.md | 167 +++++++++++++++++++++++++++++++++++++++++++++++ list_mv.ksh | 49 +++++++------- oracle_funcs.ksh | 26 +++----- rman_db.ksh | 18 ++--- rman_logs.ksh | 20 ++---- rubrik_mv_op.ksh | 12 +--- 6 files changed, 210 insertions(+), 82 deletions(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..916059b --- /dev/null +++ b/README.md @@ -0,0 +1,167 @@ +# Rubrik Oracle Backup Scripts for HP-UX + +This collection of Korn shell (ksh) scripts provides automated backup solutions for Oracle databases using Rubrik Managed Volumes (MVs) on HP-UX systems. The scripts are designed to be HP-UX compatible and handle RMAN backups with incremental merge functionality. + +## Prerequisites + +- **Operating System**: HP-UX 11i or later (also works on Linux/Solaris/AIX) +- **Shell**: Korn shell (ksh) - standard on HP-UX +- **Tools**: curl, awk, egrep, date, expr, mkdir, hostname, ps, find, chmod +- **Oracle**: Oracle Database with RMAN configured +- **Rubrik**: Access to Rubrik CDM with Managed Volumes configured +- **Permissions**: Scripts should be run as the Oracle user + +## RMAN Configuration + +The script will + +## Configuration + +1. Copy `rbk_api.conf.example` to `rbk_api.conf` +2. Edit `rbk_api.conf` with your Rubrik settings: + +```bash +# Rubrik API Configuration +ID="your-service-account-id" +SECRET="your-service-account-secret" +RUBRIK_IP="your-rubrik-cluster-ip" + +# Mount point prefix for Managed Volumes +MOUNTPOINT_PREFIX="/rubrik_" + +# Log retention settings +HOSTLOGRET=2 +MV_SPACE_WARN=75 + +# Logging directories +API_LOG_DIR=/tmp/rubrik +RMAN_LOG_DIR=/tmp/rubrik/rman + +# Alert settings +ALERT_EMAILS="admin@example.com" +EMAIL_SUCCESS=1 +``` + +## Scripts Overview + +### oracle_funcs.ksh +Shared functions library containing: +- API authentication and REST calls +- Managed Volume operations (open/close) +- Error handling and logging +- OS detection and date handling + +### list_mv.ksh +Lists all Managed Volumes visible to the configured service account, showing each MV's name and `isWritable` status. + +**Usage:** +```bash +./list_mv.ksh +``` + +**Output:** +``` +Service account in use is client|... +Managed Volumes visible to this account: +mv_name_1: isWritable=true +mv_name_2: isWritable=false +``` + +### rubrik_mv_op.ksh +Opens or closes a Managed Volume for backup operations. + +**Usage:** +```bash +./rubrik_mv_op.ksh -d -v -o +``` + +**Examples:** +```bash +# Open data volume for ORCL database +./rubrik_mv_op.ksh -d ORCL -v data -o open + +# Close logs volume for ORCL database +./rubrik_mv_op.ksh -d ORCL -v logs -o close +``` + +### rman_db.ksh +Performs RMAN database backup with incremental merge to Rubrik Managed Volume. + +**Usage:** +```bash +./rman_db.ksh +``` + +**Features:** +- Incremental level 1 backup with merge +- Automatic MV open/close +- Disk space monitoring +- Email alerts on failure/success +- Archive log backup + +### rman_logs.ksh +Performs RMAN archive log backup to Rubrik Managed Volume. + +**Usage:** +```bash +./rman_logs.ksh +``` + +**Features:** +- Backs up all not-backed-up archive logs +- Automatic MV open/close +- Disk space monitoring +- Optional host-side log purging +- Email alerts + +## HP-UX Compatibility Notes + +These scripts are specifically designed for HP-UX compatibility: + +- Uses `ksh` instead of `bash` +- Avoids GNU-specific commands (`grep -o`, `readlink`) +- Portable `awk` for JSON parsing +- HP-UX date handling with fallback to GNU date +- No reliance on symlinks for script location detection + +## Logging + +- API calls are logged to `$API_LOG_DIR/api_calls.log` +- RMAN operations are logged to `$RMAN_LOG_DIR/$ORACLE_SID/` +- Use `tail -f` on log files for monitoring + +## Troubleshooting + +### Common Issues + +1. **"readlink not found"**: Scripts use portable directory detection +2. **JSON parsing errors**: Ensure Rubrik API returns expected format +3. **MV not found**: Check MV naming convention: `${HOST}_${ORACLE_SID}_data/logs` +4. **Permission denied**: Run as Oracle user, ensure MV mount points are accessible +5. **Curl errors**: Check network connectivity to Rubrik cluster + +### Debug Mode + +Add debug output by modifying scripts to show raw API responses. + +### Testing Compatibility + +Run the included `test.ksh` script to verify HP-UX compatibility of required tools. + +## Security Notes + +- Store `rbk_api.conf` securely with appropriate permissions +- Service account should have minimal required permissions +- Avoid logging secrets in log files + +## Support + +For issues specific to Rubrik CDM or Oracle integration, consult: +- Rubrik documentation +- Oracle RMAN documentation +- HP-UX system administration guides + +## Version History + +- v1.1: Enhanced list_mv.ksh with isWritable status, HP-UX compatibility improvements +- v1.0: Initial release with basic RMAN backup functionality \ No newline at end of file diff --git a/list_mv.ksh b/list_mv.ksh index e1c2e10..5506fe2 100755 --- a/list_mv.ksh +++ b/list_mv.ksh @@ -6,43 +6,42 @@ # # usage: list_mv.ksh - get_script_dir() { - # Portable way to get script directory for Linux and HP/UX (ksh compatible) src="$0" - while [ -h "$src" ]; do - dir=$(cd -P $(dirname "$src") >/dev/null 2>&1 && pwd) - src=$(readlink "$src") - case $src in - /*) ;; # absolute path - *) src="$dir/$src";; - esac - done - cd -P $(dirname "$src") >/dev/null 2>&1 && pwd + dir=$(cd -P "$(dirname "$src")" >/dev/null 2>&1 && pwd) + echo "$dir" } MYDIR=$(get_script_dir) -. $MYDIR/rbk_api.conf +. $MYDIR/rubrik.conf . $MYDIR/oracle_funcs.ksh # Script starts here echo "Service account in use is $ID" - -echo "Managed Volumes" - +echo "Managed Volumes visible to this account:" ENDPOINT="https://$RUBRIK_IP/api/internal/managed_volume" rest_api_get -awk '{ - pos = 1 - while (match(substr($0, pos), /"name":"[^"]*"/)) { - name = substr($0, pos + RSTART + 7, RLENGTH - 8) - # Remove any trailing quote if present - sub(/"$/, "", name) - print name - pos += RSTART + RLENGTH - 1 - } -}' /tmp/rbkresponse.$$ +awk ' +{ + + line = $0 + pos = 1 + while (match(substr(line, pos), /"name":"[^"]*"/)) { + start = pos + RSTART + 7 + len = RLENGTH - 9 + name = substr(line, start, len) + pos += RSTART + RLENGTH - 1 + if (match(substr(line, pos), /"isWritable":[ ]*(true|false)/)) { + start_w = pos + RSTART + 12 + len_w = RLENGTH - 13 + writable = substr(line, start_w, len_w) + print name ": isWritable=" writable + pos += RSTART + RLENGTH - 1 + } + } +} +' /tmp/rbkresponse.$$ cleanup diff --git a/oracle_funcs.ksh b/oracle_funcs.ksh index 0b0b804..4770a4a 100755 --- a/oracle_funcs.ksh +++ b/oracle_funcs.ksh @@ -21,7 +21,6 @@ get_short_hostname() { } HOST=$(get_short_hostname) - # Detect OS and set DATE variable appropriately os_name=$(uname -s) case "$os_name" in @@ -50,28 +49,24 @@ echo "`$DATE` -$$-: CALLED $0 $@" >> $LOGFILE trap ctrl_c INT - ctrl_c() { echo "`$DATE` -$$-: TRAPPED CTRL-C - EXITING" >> $LOGFILE exit_with_error } - ctrl_c_inhibit() { echo "`$DATE` -$$-: TRAPPED CTRL-C - CONTINUING" >> $LOGFILE } exit_with_error() { -# if [ $usingsatoken ]; then -# ENDPOINT="https://$RUBRIK_IP/api/internal/session/me" -# rest_api_delete -# check_http_error -# fi + ENDPOINT="https://$RUBRIK_IP/api/v1/session/me" + rest_api_delete + check_http_error cat /tmp/rbkresponse.$$ | mailx -s "Backup error on ${HOST} for ${ORACLE_SID}. Please investigate" $ALERT_EMAILS - #rm -f /tmp/rbkresponse.$$ + rm -f /tmp/rbkresponse.$$ rm -f /tmp/mountedDBs.$$ - rm -f $PIDFILE + rm -f $PIDFILE echo Aborting Script! echo "`$DATE` -$$-: EXITED WITH ERROR $0 $@" >> $LOGFILE exit 1 @@ -301,12 +296,9 @@ close_mv() { } cleanup() { -# if [ $usingsatoken ]; then -# ENDPOINT="https://$RUBRIK_IP/api/internal/session/me" -# rest_api_delete -# fi - echo "`$DATE` -$$-: EXITED $0 $@" >> $LOGFILE - #rm -f /tmp/mountedDBs.$$ - #rm -f /tmp/rbkresponse.$$ + ENDPOINT="https://$RUBRIK_IP/api/v1/session/me" + rest_api_delete + echo "`$DATE` -$$-: EXITED $0 $@" >> $LOGFILE + rm -f /tmp/rbkresponse.$$ rm -f $PIDFILE } diff --git a/rman_db.ksh b/rman_db.ksh index fa61383..8d4fcf1 100755 --- a/rman_db.ksh +++ b/rman_db.ksh @@ -7,17 +7,9 @@ # usage: rman_db.ksh get_script_dir() { - # Portable way to get script directory for Linux and HP/UX (ksh compatible) src="$0" - while [ -h "$src" ]; do - dir=$(cd -P $(dirname "$src") >/dev/null 2>&1 && pwd) - src=$(readlink "$src") - case $src in - /*) ;; # absolute path - *) src="$dir/$src";; - esac - done - cd -P $(dirname "$src") >/dev/null 2>&1 && pwd + dir=$(cd -P "$(dirname "$src")" >/dev/null 2>&1 && pwd) + echo "$dir" } MYDIR=$(get_script_dir) @@ -32,7 +24,7 @@ export ORACLE_SID=$1 export ORAENV_ASK=YES -. $MYDIR/rbk_api.conf +. $MYDIR/rubrik.conf . $MYDIR/oracle_funcs.ksh #ORACLE_SID=$1 @@ -46,9 +38,6 @@ 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 @@ -109,6 +98,7 @@ connect target / set echo on; configure retention policy to recovery window of 1 days; run { +CONFIGURE BACKUP OPTIMIZATION OFF; 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; diff --git a/rman_logs.ksh b/rman_logs.ksh index 148383a..8e12488 100755 --- a/rman_logs.ksh +++ b/rman_logs.ksh @@ -7,17 +7,9 @@ # usage: rman_logs.ksh get_script_dir() { - # Portable way to get script directory for Linux and HP/UX (ksh compatible) src="$0" - while [ -h "$src" ]; do - dir=$(cd -P $(dirname "$src") >/dev/null 2>&1 && pwd) - src=$(readlink "$src") - case $src in - /*) ;; # absolute path - *) src="$dir/$src";; - esac - done - cd -P $(dirname "$src") >/dev/null 2>&1 && pwd + dir=$(cd -P "$(dirname "$src")" >/dev/null 2>&1 && pwd) + echo "$dir" } MYDIR=$(get_script_dir) export ORACLE_SID=$1 @@ -31,11 +23,9 @@ export ORACLE_SID=$1 export ORAENV_ASK=YES -. $MYDIR/rbk_api.conf +. $MYDIR/rubrik.conf . $MYDIR/oracle_funcs.ksh -#ORACLE_SID=$1 - usage() { echo "Usage: $0 ]" 1>&2 exit 1 @@ -45,9 +35,6 @@ 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 @@ -94,6 +81,7 @@ set echo on; show all; crosscheck backup; run { +CONFIGURE BACKUP OPTIMIZATION OFF; set controlfile autobackup format for device type disk to '$channel0/cf_%F'; $allocate backup archivelog all not backed up 1 times tag 'rubrik_pit_logs'; diff --git a/rubrik_mv_op.ksh b/rubrik_mv_op.ksh index f72a99c..4443414 100755 --- a/rubrik_mv_op.ksh +++ b/rubrik_mv_op.ksh @@ -11,17 +11,9 @@ # -o Operation to perform - open or close the MV get_script_dir() { - # Portable way to get script directory for Linux and HP/UX (ksh compatible) src="$0" - while [ -h "$src" ]; do - dir=$(cd -P $(dirname "$src") >/dev/null 2>&1 && pwd) - src=$(readlink "$src") - case $src in - /*) ;; # absolute path - *) src="$dir/$src";; - esac - done - cd -P $(dirname "$src") >/dev/null 2>&1 && pwd + dir=$(cd -P "$(dirname "$src")" >/dev/null 2>&1 && pwd) + echo "$dir" } MYDIR=$(get_script_dir) . $MYDIR/rbk_api.conf