HP/UX fixes
This commit is contained in:
167
README.md
Normal file
167
README.md
Normal file
@@ -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 <DBNAME> -v <logs|data> -o <open|close>
|
||||||
|
```
|
||||||
|
|
||||||
|
**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 <ORACLE_SID>
|
||||||
|
```
|
||||||
|
|
||||||
|
**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 <ORACLE_SID>
|
||||||
|
```
|
||||||
|
|
||||||
|
**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
|
||||||
49
list_mv.ksh
49
list_mv.ksh
@@ -6,43 +6,42 @@
|
|||||||
#
|
#
|
||||||
# usage: list_mv.ksh
|
# usage: list_mv.ksh
|
||||||
|
|
||||||
|
|
||||||
get_script_dir() {
|
get_script_dir() {
|
||||||
# Portable way to get script directory for Linux and HP/UX (ksh compatible)
|
|
||||||
src="$0"
|
src="$0"
|
||||||
while [ -h "$src" ]; do
|
dir=$(cd -P "$(dirname "$src")" >/dev/null 2>&1 && pwd)
|
||||||
dir=$(cd -P $(dirname "$src") >/dev/null 2>&1 && pwd)
|
echo "$dir"
|
||||||
src=$(readlink "$src")
|
|
||||||
case $src in
|
|
||||||
/*) ;; # absolute path
|
|
||||||
*) src="$dir/$src";;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
cd -P $(dirname "$src") >/dev/null 2>&1 && pwd
|
|
||||||
}
|
}
|
||||||
MYDIR=$(get_script_dir)
|
MYDIR=$(get_script_dir)
|
||||||
. $MYDIR/rbk_api.conf
|
. $MYDIR/rubrik.conf
|
||||||
. $MYDIR/oracle_funcs.ksh
|
. $MYDIR/oracle_funcs.ksh
|
||||||
|
|
||||||
# Script starts here
|
# Script starts here
|
||||||
|
|
||||||
echo "Service account in use is $ID"
|
echo "Service account in use is $ID"
|
||||||
|
echo "Managed Volumes visible to this account:"
|
||||||
echo "Managed Volumes"
|
|
||||||
|
|
||||||
|
|
||||||
ENDPOINT="https://$RUBRIK_IP/api/internal/managed_volume"
|
ENDPOINT="https://$RUBRIK_IP/api/internal/managed_volume"
|
||||||
rest_api_get
|
rest_api_get
|
||||||
|
|
||||||
awk '{
|
awk '
|
||||||
pos = 1
|
{
|
||||||
while (match(substr($0, pos), /"name":"[^"]*"/)) {
|
|
||||||
name = substr($0, pos + RSTART + 7, RLENGTH - 8)
|
line = $0
|
||||||
# Remove any trailing quote if present
|
pos = 1
|
||||||
sub(/"$/, "", name)
|
while (match(substr(line, pos), /"name":"[^"]*"/)) {
|
||||||
print name
|
start = pos + RSTART + 7
|
||||||
pos += RSTART + RLENGTH - 1
|
len = RLENGTH - 9
|
||||||
}
|
name = substr(line, start, len)
|
||||||
}' /tmp/rbkresponse.$$
|
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
|
cleanup
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ get_short_hostname() {
|
|||||||
}
|
}
|
||||||
HOST=$(get_short_hostname)
|
HOST=$(get_short_hostname)
|
||||||
|
|
||||||
|
|
||||||
# Detect OS and set DATE variable appropriately
|
# Detect OS and set DATE variable appropriately
|
||||||
os_name=$(uname -s)
|
os_name=$(uname -s)
|
||||||
case "$os_name" in
|
case "$os_name" in
|
||||||
@@ -50,28 +49,24 @@ echo "`$DATE` -$$-: CALLED $0 $@" >> $LOGFILE
|
|||||||
|
|
||||||
trap ctrl_c INT
|
trap ctrl_c INT
|
||||||
|
|
||||||
|
|
||||||
ctrl_c() {
|
ctrl_c() {
|
||||||
echo "`$DATE` -$$-: TRAPPED CTRL-C - EXITING" >> $LOGFILE
|
echo "`$DATE` -$$-: TRAPPED CTRL-C - EXITING" >> $LOGFILE
|
||||||
exit_with_error
|
exit_with_error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ctrl_c_inhibit() {
|
ctrl_c_inhibit() {
|
||||||
echo "`$DATE` -$$-: TRAPPED CTRL-C - CONTINUING" >> $LOGFILE
|
echo "`$DATE` -$$-: TRAPPED CTRL-C - CONTINUING" >> $LOGFILE
|
||||||
}
|
}
|
||||||
|
|
||||||
exit_with_error() {
|
exit_with_error() {
|
||||||
# if [ $usingsatoken ]; then
|
ENDPOINT="https://$RUBRIK_IP/api/v1/session/me"
|
||||||
# ENDPOINT="https://$RUBRIK_IP/api/internal/session/me"
|
rest_api_delete
|
||||||
# rest_api_delete
|
check_http_error
|
||||||
# check_http_error
|
|
||||||
# fi
|
|
||||||
|
|
||||||
cat /tmp/rbkresponse.$$ | mailx -s "Backup error on ${HOST} for ${ORACLE_SID}. Please investigate" $ALERT_EMAILS
|
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 /tmp/mountedDBs.$$
|
||||||
rm -f $PIDFILE
|
rm -f $PIDFILE
|
||||||
echo Aborting Script!
|
echo Aborting Script!
|
||||||
echo "`$DATE` -$$-: EXITED WITH ERROR $0 $@" >> $LOGFILE
|
echo "`$DATE` -$$-: EXITED WITH ERROR $0 $@" >> $LOGFILE
|
||||||
exit 1
|
exit 1
|
||||||
@@ -301,12 +296,9 @@ close_mv() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
# if [ $usingsatoken ]; then
|
ENDPOINT="https://$RUBRIK_IP/api/v1/session/me"
|
||||||
# ENDPOINT="https://$RUBRIK_IP/api/internal/session/me"
|
rest_api_delete
|
||||||
# rest_api_delete
|
echo "`$DATE` -$$-: EXITED $0 $@" >> $LOGFILE
|
||||||
# fi
|
rm -f /tmp/rbkresponse.$$
|
||||||
echo "`$DATE` -$$-: EXITED $0 $@" >> $LOGFILE
|
|
||||||
#rm -f /tmp/mountedDBs.$$
|
|
||||||
#rm -f /tmp/rbkresponse.$$
|
|
||||||
rm -f $PIDFILE
|
rm -f $PIDFILE
|
||||||
}
|
}
|
||||||
|
|||||||
18
rman_db.ksh
18
rman_db.ksh
@@ -7,17 +7,9 @@
|
|||||||
# usage: rman_db.ksh <ORACLE_SID>
|
# usage: rman_db.ksh <ORACLE_SID>
|
||||||
|
|
||||||
get_script_dir() {
|
get_script_dir() {
|
||||||
# Portable way to get script directory for Linux and HP/UX (ksh compatible)
|
|
||||||
src="$0"
|
src="$0"
|
||||||
while [ -h "$src" ]; do
|
dir=$(cd -P "$(dirname "$src")" >/dev/null 2>&1 && pwd)
|
||||||
dir=$(cd -P $(dirname "$src") >/dev/null 2>&1 && pwd)
|
echo "$dir"
|
||||||
src=$(readlink "$src")
|
|
||||||
case $src in
|
|
||||||
/*) ;; # absolute path
|
|
||||||
*) src="$dir/$src";;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
cd -P $(dirname "$src") >/dev/null 2>&1 && pwd
|
|
||||||
}
|
}
|
||||||
MYDIR=$(get_script_dir)
|
MYDIR=$(get_script_dir)
|
||||||
|
|
||||||
@@ -32,7 +24,7 @@ export ORACLE_SID=$1
|
|||||||
|
|
||||||
export ORAENV_ASK=YES
|
export ORAENV_ASK=YES
|
||||||
|
|
||||||
. $MYDIR/rbk_api.conf
|
. $MYDIR/rubrik.conf
|
||||||
. $MYDIR/oracle_funcs.ksh
|
. $MYDIR/oracle_funcs.ksh
|
||||||
|
|
||||||
#ORACLE_SID=$1
|
#ORACLE_SID=$1
|
||||||
@@ -46,9 +38,6 @@ if [ -z "${ORACLE_SID}" ]; then
|
|||||||
usage
|
usage
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#ORAENV_ASK=NO
|
|
||||||
#. oraenv
|
|
||||||
|
|
||||||
export NLS_DATE_FORMAT='mm-dd-yyyy hh24:mi:ss'
|
export NLS_DATE_FORMAT='mm-dd-yyyy hh24:mi:ss'
|
||||||
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
|
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
|
||||||
|
|
||||||
@@ -109,6 +98,7 @@ connect target /
|
|||||||
set echo on;
|
set echo on;
|
||||||
configure retention policy to recovery window of 1 days;
|
configure retention policy to recovery window of 1 days;
|
||||||
run {
|
run {
|
||||||
|
CONFIGURE BACKUP OPTIMIZATION OFF;
|
||||||
set controlfile autobackup format for device type disk to '$channel0/cf_%F';
|
set controlfile autobackup format for device type disk to '$channel0/cf_%F';
|
||||||
$allocate
|
$allocate
|
||||||
backup incremental level 1 for recover of copy with tag 'rubrik_snap' database;
|
backup incremental level 1 for recover of copy with tag 'rubrik_snap' database;
|
||||||
|
|||||||
@@ -7,17 +7,9 @@
|
|||||||
# usage: rman_logs.ksh <ORACLE_SID>
|
# usage: rman_logs.ksh <ORACLE_SID>
|
||||||
|
|
||||||
get_script_dir() {
|
get_script_dir() {
|
||||||
# Portable way to get script directory for Linux and HP/UX (ksh compatible)
|
|
||||||
src="$0"
|
src="$0"
|
||||||
while [ -h "$src" ]; do
|
dir=$(cd -P "$(dirname "$src")" >/dev/null 2>&1 && pwd)
|
||||||
dir=$(cd -P $(dirname "$src") >/dev/null 2>&1 && pwd)
|
echo "$dir"
|
||||||
src=$(readlink "$src")
|
|
||||||
case $src in
|
|
||||||
/*) ;; # absolute path
|
|
||||||
*) src="$dir/$src";;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
cd -P $(dirname "$src") >/dev/null 2>&1 && pwd
|
|
||||||
}
|
}
|
||||||
MYDIR=$(get_script_dir)
|
MYDIR=$(get_script_dir)
|
||||||
export ORACLE_SID=$1
|
export ORACLE_SID=$1
|
||||||
@@ -31,11 +23,9 @@ export ORACLE_SID=$1
|
|||||||
|
|
||||||
export ORAENV_ASK=YES
|
export ORAENV_ASK=YES
|
||||||
|
|
||||||
. $MYDIR/rbk_api.conf
|
. $MYDIR/rubrik.conf
|
||||||
. $MYDIR/oracle_funcs.ksh
|
. $MYDIR/oracle_funcs.ksh
|
||||||
|
|
||||||
#ORACLE_SID=$1
|
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "Usage: $0 <DBNAME>]" 1>&2
|
echo "Usage: $0 <DBNAME>]" 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
@@ -45,9 +35,6 @@ if [ -z "${ORACLE_SID}" ]; then
|
|||||||
usage
|
usage
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#ORAENV_ASK=NO
|
|
||||||
#. oraenv
|
|
||||||
|
|
||||||
export NLS_DATE_FORMAT='mm-dd-yyyy hh24:mi:ss'
|
export NLS_DATE_FORMAT='mm-dd-yyyy hh24:mi:ss'
|
||||||
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
|
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
|
||||||
|
|
||||||
@@ -94,6 +81,7 @@ set echo on;
|
|||||||
show all;
|
show all;
|
||||||
crosscheck backup;
|
crosscheck backup;
|
||||||
run {
|
run {
|
||||||
|
CONFIGURE BACKUP OPTIMIZATION OFF;
|
||||||
set controlfile autobackup format for device type disk to '$channel0/cf_%F';
|
set controlfile autobackup format for device type disk to '$channel0/cf_%F';
|
||||||
$allocate
|
$allocate
|
||||||
backup archivelog all not backed up 1 times tag 'rubrik_pit_logs';
|
backup archivelog all not backed up 1 times tag 'rubrik_pit_logs';
|
||||||
|
|||||||
@@ -11,17 +11,9 @@
|
|||||||
# -o Operation to perform - open or close the MV
|
# -o Operation to perform - open or close the MV
|
||||||
|
|
||||||
get_script_dir() {
|
get_script_dir() {
|
||||||
# Portable way to get script directory for Linux and HP/UX (ksh compatible)
|
|
||||||
src="$0"
|
src="$0"
|
||||||
while [ -h "$src" ]; do
|
dir=$(cd -P "$(dirname "$src")" >/dev/null 2>&1 && pwd)
|
||||||
dir=$(cd -P $(dirname "$src") >/dev/null 2>&1 && pwd)
|
echo "$dir"
|
||||||
src=$(readlink "$src")
|
|
||||||
case $src in
|
|
||||||
/*) ;; # absolute path
|
|
||||||
*) src="$dir/$src";;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
cd -P $(dirname "$src") >/dev/null 2>&1 && pwd
|
|
||||||
}
|
}
|
||||||
MYDIR=$(get_script_dir)
|
MYDIR=$(get_script_dir)
|
||||||
. $MYDIR/rbk_api.conf
|
. $MYDIR/rbk_api.conf
|
||||||
|
|||||||
Reference in New Issue
Block a user