#!/bin/bash
################################################################################
# Oracle 19c RAC Database Administration Script
# Description: Main menu-driven script for Oracle RAC administration tasks
# Version: 2.0 (Integrated)
# Created: 2025-11-02
# Updated: 2025-11-10 - Updated to use integrated functions_common.sh
################################################################################
# Get script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Source configuration file
CONFIG_FILE="${SCRIPT_DIR}/oracle_admin.conf"
if [[ ! -f "${CONFIG_FILE}" ]]; then
echo "ERROR: Configuration file not found: ${CONFIG_FILE}"
exit 1
fi
source "${CONFIG_FILE}"
# Source common functions (INTEGRATED - includes all DG functions)
source "${SCRIPT_DIR}/functions_common.sh" || {
echo "ERROR: Cannot load functions_common.sh"
exit 1
}
# Source function libraries
source "${SCRIPT_DIR}/functions_db_health.sh" || {
echo "ERROR: Cannot load functions_db_health.sh"
exit 1
}
source "${SCRIPT_DIR}/functions_dg_health.sh" || {
echo "ERROR: Cannot load functions_dg_health.sh"
exit 1
}
source "${SCRIPT_DIR}/functions_dg_switchover.sh" || {
echo "ERROR: Cannot load functions_dg_switchover.sh"
exit 1
}
source "${SCRIPT_DIR}/functions_restore_point.sh" || {
echo "ERROR: Cannot load functions_restore_point.sh"
exit 1
}
################################################################################
# Global Variables
################################################################################
SCRIPT_VERSION="2.0"
SCRIPT_NAME="Oracle 19c RAC Administration"
################################################################################
# Function: show_banner
# Description: Displays the script banner
################################################################################
show_banner() {
clear
echo "==============================================================================="
echo " ${SCRIPT_NAME} - Version ${SCRIPT_VERSION}"
echo "==============================================================================="
echo " Oracle Home: ${ORACLE_HOME}"
echo " User: $(whoami)"
echo " Date: $(date '+%Y-%m-%d %H:%M:%S')"
echo "==============================================================================="
echo ""
}
################################################################################
# Function: show_main_menu
# Description: Displays the main menu
################################################################################
show_main_menu() {
echo ""
echo "=== MAIN MENU ==="
echo ""
echo "1. Database Health Check"
echo "2. Data Guard Health Check"
echo "3. Data Guard Switchover"
echo "4. Restore Point Management"
echo "5. System Configuration"
echo "6. View Logs"
echo "7. Cleanup Old Reports"
echo "0. Exit"
echo ""
echo -n "Enter your choice: "
}
################################################################################
# Function: select_database
# Description: Prompts user to select a database from the list
# Returns: Selected database configuration (DB_NAME|SCAN|SERVICE)
################################################################################
select_database() {
local prompt_message=$1
echo ""
echo "=== ${prompt_message} ==="
echo ""
# Load all databases
local all_dbs=$(load_database_list "ALL")
if [[ -z "${all_dbs}" ]]; then
log_message "ERROR" "No databases found in configuration"
echo "ERROR: No databases configured"
return 1
fi
# Display database list
local idx=1
declare -A db_map
echo "Available Databases:"
echo ""
while IFS= read -r db_line; do
IFS='|' read -r db scan service <<< "${db_line}"
echo " ${idx}. ${db} (${scan}/${service})"
db_map[$idx]="${db_line}"
((idx++))
done <<< "${all_dbs}"
echo " A. ALL Databases"
echo " M. Manual Input"
echo " 0. Cancel"
echo ""
echo -n "Enter your choice: "
read choice
case ${choice} in
0)
echo "Operation cancelled"
return 1
;;
[Aa])
echo "ALL"
return 0
;;
[Mm])
echo ""
echo -n "Enter database name: "
read manual_db
if [[ -z "${manual_db}" ]]; then
echo "ERROR: Database name cannot be empty"
return 1
fi
local manual_config=$(load_database_list "${manual_db}")
if [[ -z "${manual_config}" ]]; then
echo "ERROR: Database '${manual_db}' not found in configuration"
return 1
fi
echo "${manual_config}"
return 0
;;
*)
if [[ -n "${db_map[$choice]}" ]]; then
echo "${db_map[$choice]}"
return 0
else
echo "ERROR: Invalid choice"
return 1
fi
;;
esac
}
################################################################################
# Function: display_database_details
# Description: Displays selected database connection details
# Parameters: $1 - Database configuration (DB_NAME|SCAN|SERVICE or "ALL")
################################################################################
display_database_details() {
local selection=$1
if [[ "${selection}" == "ALL" ]]; then
echo ""
echo "Selected: ALL Databases"
echo ""
local all_dbs=$(load_database_list "ALL")
while IFS= read -r db_line; do
IFS='|' read -r db scan service <<< "${db_line}"
echo " - ${db}: ${scan}/${service}"
done <<< "${all_dbs}"
else
IFS='|' read -r db scan service <<< "${selection}"
echo ""
echo "Selected Database Details:"
echo " Database: ${db}"
echo " SCAN Address: ${scan}"
echo " Service Name: ${service}"
echo " Connection: ${scan}/${service}"
fi
echo ""
}
################################################################################
# Function: menu_database_health_check
# Description: Handles database health check menu option
################################################################################
menu_database_health_check() {
show_banner
local selected_db=$(select_database "Select Database for Health Check")
if [[ $? -ne 0 ]] || [[ -z "${selected_db}" ]]; then
echo "No database selected"
read -p "Press Enter to continue..."
return 1
fi
display_database_details "${selected_db}"
echo "Starting Database Health Check..."
echo ""
if [[ "${selected_db}" == "ALL" ]]; then
perform_db_health_check_all
else
IFS='|' read -r db_name scan service <<< "${selected_db}"
perform_db_health_check "${db_name}" "${scan}" "${service}"
fi
echo ""
read -p "Press Enter to continue..."
}
################################################################################
# Function: menu_dg_health_check
# Description: Handles Data Guard health check menu option
################################################################################
menu_dg_health_check() {
show_banner
local selected_db=$(select_database "Select Database for DG Health Check")
if [[ $? -ne 0 ]] || [[ -z "${selected_db}" ]]; then
echo "No database selected"
read -p "Press Enter to continue..."
return 1
fi
display_database_details "${selected_db}"
echo "Starting Data Guard Health Check..."
echo ""
if [[ "${selected_db}" == "ALL" ]]; then
perform_dg_health_check_all
else
IFS='|' read -r db_name scan service <<< "${selected_db}"
perform_dg_health_check "${db_name}"
fi
echo ""
read -p "Press Enter to continue..."
}
################################################################################
# Function: menu_dg_switchover
# Description: Handles Data Guard switchover menu option
################################################################################
menu_dg_switchover() {
show_banner
local selected_db=$(select_database "Select Source Database for Switchover")
if [[ $? -ne 0 ]] || [[ -z "${selected_db}" ]] || [[ "${selected_db}" == "ALL" ]]; then
echo "Invalid selection - switchover requires specific database"
read -p "Press Enter to continue..."
return 1
fi
IFS='|' read -r db_name scan service <<< "${selected_db}"
display_database_details "${selected_db}"
echo "Initiating Data Guard Switchover Process..."
echo ""
echo "WARNING: This will perform an actual database role change!"
echo ""
echo -n "Type 'YES' to continue or anything else to cancel: "
read confirmation
if [[ "${confirmation}" != "YES" ]]; then
echo "Switchover cancelled"
read -p "Press Enter to continue..."
return 1
fi
perform_dg_switchover "${db_name}"
echo ""
read -p "Press Enter to continue..."
}
################################################################################
# Function: menu_restore_point
# Description: Handles restore point management menu option
################################################################################
menu_restore_point() {
show_banner
echo "=== RESTORE POINT MANAGEMENT ==="
echo ""
echo "1. Create Restore Point (Primary Only)"
echo "2. Create Restore Point (All DG Members)"
echo "3. List Restore Points"
echo "4. Drop Restore Point (Primary Only)"
echo "5. Drop Restore Point (All DG Members)"
echo "0. Back to Main Menu"
echo ""
echo -n "Enter your choice: "
read rp_choice
case ${rp_choice} in
1)
menu_create_restore_point_primary
;;
2)
menu_create_restore_point_all
;;
3)
menu_list_restore_points
;;
4)
menu_drop_restore_point_primary
;;
5)
menu_drop_restore_point_all
;;
0)
return 0
;;
*)
echo "Invalid choice"
read -p "Press Enter to continue..."
;;
esac
}
################################################################################
# Function: menu_create_restore_point_primary
# Description: Creates restore point on primary database only
################################################################################
menu_create_restore_point_primary() {
local selected_db=$(select_database "Select Database for Restore Point")
if [[ $? -ne 0 ]] || [[ -z "${selected_db}" ]] || [[ "${selected_db}" == "ALL" ]]; then
echo "Invalid selection"
read -p "Press Enter to continue..."
return 1
fi
IFS='|' read -r db_name scan service <<< "${selected_db}"
display_database_details "${selected_db}"
echo -n "Enter restore point name: "
read rp_name
if [[ -z "${rp_name}" ]]; then
echo "ERROR: Restore point name cannot be empty"
read -p "Press Enter to continue..."
return 1
fi
create_restore_point_primary "${db_name}" "${scan}" "${service}" "${rp_name}"
read -p "Press Enter to continue..."
}
################################################################################
# Function: menu_create_restore_point_all
# Description: Creates restore point on all DG members
################################################################################
menu_create_restore_point_all() {
local selected_db=$(select_database "Select Database Configuration")
if [[ $? -ne 0 ]] || [[ -z "${selected_db}" ]] || [[ "${selected_db}" == "ALL" ]]; then
echo "Invalid selection"
read -p "Press Enter to continue..."
return 1
fi
IFS='|' read -r db_name scan service <<< "${selected_db}"
display_database_details "${selected_db}"
echo -n "Enter restore point name: "
read rp_name
if [[ -z "${rp_name}" ]]; then
echo "ERROR: Restore point name cannot be empty"
read -p "Press Enter to continue..."
return 1
fi
create_restore_point_all_dg_members "${db_name}" "${rp_name}"
read -p "Press Enter to continue..."
}
################################################################################
# Function: menu_list_restore_points
# Description: Lists restore points
################################################################################
menu_list_restore_points() {
local selected_db=$(select_database "Select Database to List Restore Points")
if [[ $? -ne 0 ]] || [[ -z "${selected_db}" ]] || [[ "${selected_db}" == "ALL" ]]; then
echo "Invalid selection"
read -p "Press Enter to continue..."
return 1
fi
IFS='|' read -r db_name scan service <<< "${selected_db}"
display_database_details "${selected_db}"
list_restore_points "${db_name}" "${scan}" "${service}"
read -p "Press Enter to continue..."
}
################################################################################
# Function: menu_drop_restore_point_primary
# Description: Drops restore point from primary database
################################################################################
menu_drop_restore_point_primary() {
local selected_db=$(select_database "Select Database")
if [[ $? -ne 0 ]] || [[ -z "${selected_db}" ]] || [[ "${selected_db}" == "ALL" ]]; then
echo "Invalid selection"
read -p "Press Enter to continue..."
return 1
fi
IFS='|' read -r db_name scan service <<< "${selected_db}"
display_database_details "${selected_db}"
# List current restore points first
list_restore_points "${db_name}" "${scan}" "${service}"
echo ""
echo -n "Enter restore point name to drop: "
read rp_name
if [[ -z "${rp_name}" ]]; then
echo "ERROR: Restore point name cannot be empty"
read -p "Press Enter to continue..."
return 1
fi
drop_restore_point_primary "${db_name}" "${scan}" "${service}" "${rp_name}"
read -p "Press Enter to continue..."
}
################################################################################
# Function: menu_drop_restore_point_all
# Description: Drops restore point from all DG members
################################################################################
menu_drop_restore_point_all() {
local selected_db=$(select_database "Select Database Configuration")
if [[ $? -ne 0 ]] || [[ -z "${selected_db}" ]] || [[ "${selected_db}" == "ALL" ]]; then
echo "Invalid selection"
read -p "Press Enter to continue..."
return 1
fi
IFS='|' read -r db_name scan service <<< "${selected_db}"
display_database_details "${selected_db}"
echo -n "Enter restore point name to drop: "
read rp_name
if [[ -z "${rp_name}" ]]; then
echo "ERROR: Restore point name cannot be empty"
read -p "Press Enter to continue..."
return 1
fi
drop_restore_point_all_dg_members "${db_name}" "${rp_name}"
read -p "Press Enter to continue..."
}
################################################################################
# Function: menu_system_configuration
# Description: Handles system configuration menu option
################################################################################
menu_system_configuration() {
show_banner
echo "=== SYSTEM CONFIGURATION ==="
echo ""
echo "1. View Configuration"
echo "2. Edit Configuration File"
echo "3. View Database List"
echo "4. Edit Database List"
echo "5. Test Email Configuration"
echo "0. Back to Main Menu"
echo ""
echo -n "Enter your choice: "
read config_choice
case ${config_choice} in
1)
view_configuration
;;
2)
edit_configuration
;;
3)
view_database_list
;;
4)
edit_database_list
;;
5)
test_email_configuration
;;
0)
return 0
;;
*)
echo "Invalid choice"
read -p "Press Enter to continue..."
;;
esac
}
################################################################################
# Function: view_configuration
# Description: Displays current configuration (passwords masked)
################################################################################
view_configuration() {
echo ""
echo "=== CURRENT CONFIGURATION ==="
echo ""
echo "Oracle Environment:"
echo " ORACLE_HOME: ${ORACLE_HOME}"
echo " ORACLE_BASE: ${ORACLE_BASE:-Not set}"
echo ""
echo "Database Connection:"
echo " SYS_USER: ${SYS_USER}"
echo " SYS_PASSWORD: ********"
echo ""
echo "File Locations:"
echo " DATABASE_LIST_FILE: ${DATABASE_LIST_FILE}"
echo " LOG_BASE_DIR: ${LOG_BASE_DIR}"
echo " REPORT_BASE_DIR: ${REPORT_BASE_DIR}"
echo ""
echo "Email Configuration:"
echo " SEND_EMAIL: ${SEND_EMAIL:-NO}"
echo " EMAIL_FROM: ${EMAIL_FROM:-Not set}"
echo " EMAIL_RECIPIENTS: ${EMAIL_RECIPIENTS:-Not set}"
echo ""
read -p "Press Enter to continue..."
}
################################################################################
# Function: edit_configuration
# Description: Opens configuration file in editor
################################################################################
edit_configuration() {
echo ""
echo "Opening configuration file in editor..."
${EDITOR:-vi} "${CONFIG_FILE}"
echo ""
echo "Configuration file updated"
echo "NOTE: Restart the script for changes to take effect"
read -p "Press Enter to continue..."
}
################################################################################
# Function: view_database_list
# Description: Displays database list
################################################################################
view_database_list() {
echo ""
echo "=== DATABASE LIST ==="
echo ""
if [[ ! -f "${DATABASE_LIST_FILE}" ]]; then
echo "ERROR: Database list file not found: ${DATABASE_LIST_FILE}"
read -p "Press Enter to continue..."
return 1
fi
cat "${DATABASE_LIST_FILE}"
echo ""
read -p "Press Enter to continue..."
}
################################################################################
# Function: edit_database_list
# Description: Opens database list in editor
################################################################################
edit_database_list() {
echo ""
echo "Opening database list in editor..."
${EDITOR:-vi} "${DATABASE_LIST_FILE}"
echo ""
echo "Database list updated"
read -p "Press Enter to continue..."
}
################################################################################
# Function: test_email_configuration
# Description: Sends test email
################################################################################
test_email_configuration() {
echo ""
echo "=== TEST EMAIL CONFIGURATION ==="
echo ""
if [[ "${SEND_EMAIL}" != "YES" ]]; then
echo "Email is not enabled in configuration"
echo "Set SEND_EMAIL=YES in ${CONFIG_FILE}"
read -p "Press Enter to continue..."
return 1
fi
echo "Sending test email to: ${EMAIL_RECIPIENTS}"
local test_file="/tmp/oracle_admin_test_email_$$.html"
cat > "${test_file}" << 'EOF'
Test Email
Oracle RAC Administration - Test Email
This is a test email from the Oracle RAC Administration script.
If you receive this email, your email configuration is working correctly.
Generated: $(date)
EOF
if send_email_report "Oracle RAC Admin - Test Email" "${test_file}" "${EMAIL_RECIPIENTS}"; then
echo "Test email sent successfully"
else
echo "Failed to send test email"
fi
rm -f "${test_file}"
read -p "Press Enter to continue..."
}
################################################################################
# Function: menu_view_logs
# Description: Displays recent log entries
################################################################################
menu_view_logs() {
show_banner
echo "=== VIEW LOGS ==="
echo ""
local log_file="${LOG_BASE_DIR}/oracle_admin_$(date '+%Y%m%d').log"
if [[ ! -f "${log_file}" ]]; then
echo "No log file found for today: ${log_file}"
read -p "Press Enter to continue..."
return 1
fi
echo "Displaying last 50 lines from: ${log_file}"
echo ""
echo "-------------------------------------------------------------------"
tail -50 "${log_file}"
echo "-------------------------------------------------------------------"
echo ""
read -p "Press Enter to continue..."
}
################################################################################
# Function: menu_cleanup_old_reports
# Description: Cleans up old reports and logs
################################################################################
menu_cleanup_old_reports() {
show_banner
echo "=== CLEANUP OLD REPORTS ==="
echo ""
echo "This will remove files older than:"
echo " - Reports: ${REPORT_RETENTION_DAYS} days"
echo " - Logs: ${LOG_RETENTION_DAYS} days"
echo ""
echo -n "Continue? (y/n): "
read confirm
if [[ "${confirm}" != "y" ]] && [[ "${confirm}" != "Y" ]]; then
echo "Cleanup cancelled"
read -p "Press Enter to continue..."
return 0
fi
echo ""
echo "Cleaning up old reports..."
cleanup_old_files "${REPORT_BASE_DIR}" "${REPORT_RETENTION_DAYS}"
echo "Cleaning up old logs..."
cleanup_old_files "${LOG_BASE_DIR}" "${LOG_RETENTION_DAYS}"
echo ""
echo "Cleanup completed"
read -p "Press Enter to continue..."
}
################################################################################
# Main Script
################################################################################
# Validate prerequisites
if ! validate_prerequisites; then
echo "ERROR: Prerequisites validation failed"
exit 1
fi
log_message "INFO" "Oracle RAC Administration script started by ${USER}"
# Main loop
while true; do
show_banner
show_main_menu
read main_choice
case ${main_choice} in
1)
menu_database_health_check
;;
2)
menu_dg_health_check
;;
3)
menu_dg_switchover
;;
4)
menu_restore_point
;;
5)
menu_system_configuration
;;
6)
menu_view_logs
;;
7)
menu_cleanup_old_reports
;;
0)
echo ""
echo "Exiting Oracle RAC Administration script..."
log_message "INFO" "Oracle RAC Administration script exited by ${USER}"
exit 0
;;
*)
echo "Invalid choice. Please try again."
sleep 2
;;
esac
done
################################################################################
# End of oracle_rac_admin.sh
################################################################################