Sunday, November 9, 2025

#!/bin/bash ################################################################################ # Oracle 19c Data Guard Switchover Functions # Description: Functions for performing Data Guard switchover operations # Version: 2.0 (Integrated) # Created: 2025-11-02 # Updated: 2025-11-10 - Removed duplicate functions (now in functions_common.sh) ################################################################################ # NOTE: This file assumes functions_common.sh has already been sourced # All DG core functions are now in functions_common.sh ################################################################################ # Function: perform_dg_switchover # Description: Performs Data Guard switchover operation # Parameters: $1 - Source database name ################################################################################ perform_dg_switchover() { local source_db=$1 log_message "INFO" "Starting Data Guard switchover process for: ${source_db}" # Get DG Broker configuration if ! get_dg_broker_configuration "${source_db}"; then log_message "ERROR" "Failed to get DG Broker configuration" echo "ERROR: Not part of Data Guard configuration" return 1 fi # Get primary and standby databases if ! get_primary_database_dgmgrl; then log_message "ERROR" "Failed to identify primary database" return 1 fi if ! get_all_standby_databases_dgmgrl; then log_message "ERROR" "Failed to get standby databases" return 1 fi # Display current configuration echo "" echo "===================================================================" echo " Current Data Guard Configuration: ${DG_CONFIG_NAME}" echo "===================================================================" echo " Primary Database: ${PRIMARY_DB_UNIQUE_NAME}" echo "" echo " Standby Databases:" for standby in "${STANDBY_DBS_ARRAY[@]}"; do echo " - ${standby}" done echo "===================================================================" echo "" # If no standbys, cannot switchover if [[ ${#STANDBY_DBS_ARRAY[@]} -eq 0 ]]; then log_message "ERROR" "No standby databases found - switchover not possible" echo "ERROR: No standby databases available for switchover" return 1 fi # Select target database echo "Select target database for switchover:" echo "" local idx=1 declare -A target_map for standby in "${STANDBY_DBS_ARRAY[@]}"; do echo " ${idx}. ${standby}" target_map[$idx]="${standby}" ((idx++)) done echo " 0. Cancel" echo "" echo -n "Enter your choice: " read target_choice if [[ "${target_choice}" == "0" ]]; then echo "Switchover cancelled" return 0 fi local target_db="${target_map[$target_choice]}" if [[ -z "${target_db}" ]]; then echo "ERROR: Invalid choice" return 1 fi # Confirm switchover echo "" echo "===================================================================" echo " SWITCHOVER PLAN" echo "===================================================================" echo " Current Primary: ${PRIMARY_DB_UNIQUE_NAME}" echo " Target Primary: ${target_db}" echo "" echo " After switchover:" echo " ${PRIMARY_DB_UNIQUE_NAME} will become STANDBY" echo " ${target_db} will become PRIMARY" echo "===================================================================" echo "" echo "WARNING: This operation will change database roles!" echo "" echo -n "Type the target database name '${target_db}' to confirm: " read confirmation if [[ "${confirmation}" != "${target_db}" ]]; then echo "Confirmation failed - switchover cancelled" return 0 fi # Generate report file local report_file="${REPORT_BASE_DIR}/${DG_CONFIG_NAME}_switchover_$(date '+%Y%m%d_%H%M%S').html" mkdir -p "${REPORT_BASE_DIR}" # Perform pre-switchover validation echo "" echo "Performing pre-switchover validation..." if ! validate_switchover_readiness; then echo "" echo "ERROR: Pre-switchover validation failed" echo "Please resolve issues before attempting switchover" return 1 fi echo "Pre-switchover validation passed" # Perform the switchover echo "" echo "Executing switchover..." echo "" if execute_switchover "${target_db}" "${report_file}"; then log_message "INFO" "Switchover completed successfully" echo "" echo "===================================================================" echo " SWITCHOVER SUCCESSFUL" echo "===================================================================" echo " Report saved to: ${report_file}" echo "===================================================================" # Send email if configured if [[ "${SEND_EMAIL}" == "YES" ]]; then send_email_report "Data Guard Switchover - ${DG_CONFIG_NAME}" "${report_file}" "${EMAIL_RECIPIENTS}" fi return 0 else log_message "ERROR" "Switchover failed" echo "" echo "===================================================================" echo " SWITCHOVER FAILED" echo "===================================================================" echo " Check report for details: ${report_file}" echo "===================================================================" return 1 fi } ################################################################################ # Function: validate_switchover_readiness # Description: Validates that configuration is ready for switchover # Returns: 0 if ready, 1 if not ready ################################################################################ validate_switchover_readiness() { local issues_found=0 # Check overall DG status check_dg_status_dgmgrl if [[ "${DG_OVERALL_STATUS}" != "SUCCESS" ]]; then echo "✗ Configuration status is ${DG_OVERALL_STATUS} (must be SUCCESS)" ((issues_found++)) else echo "✓ Configuration status is SUCCESS" fi # Check standby lag for standby in "${STANDBY_DBS_ARRAY[@]}"; do check_standby_lag_dgmgrl "${standby}" if [[ "${LAG_APPLY}" == "0 seconds" ]]; then echo "✓ Standby ${standby} has no apply lag" else echo "✗ Standby ${standby} has apply lag: ${LAG_APPLY}" ((issues_found++)) fi done if [[ ${issues_found} -gt 0 ]]; then echo "" echo "${issues_found} issue(s) found" return 1 fi return 0 } ################################################################################ # Function: execute_switchover # Description: Executes the actual switchover operation # Parameters: $1 - Target database name # $2 - Report file path # Returns: 0 if successful, 1 if failed ################################################################################ execute_switchover() { local target_db=$1 local report_file=$2 # Start HTML report initialize_switchover_report "${report_file}" # Record pre-switchover state add_to_report "${report_file}" "

Pre-Switchover Configuration

" add_to_report "${report_file}" "

Primary: ${PRIMARY_DB_UNIQUE_NAME}

" add_to_report "${report_file}" "

Target: ${target_db}

" add_to_report "${report_file}" "

Start Time: $(date '+%Y-%m-%d %H:%M:%S')

" # Execute switchover using DGMGRL echo "Executing: SWITCHOVER TO ${target_db}" add_to_report "${report_file}" "

Switchover Execution

" add_to_report "${report_file}" "
"
    
    local switchover_output=$(${ORACLE_HOME}/bin/dgmgrl -silent << EOF
connect ${DG_CONNECT_STRING}
switchover to ${target_db};
exit;
EOF
)
    
    echo "${switchover_output}"
    add_to_report "${report_file}" "${switchover_output}"
    add_to_report "${report_file}" "
" # Check if switchover succeeded if echo "${switchover_output}" | grep -qi "succeed"; then echo "Switchover command executed successfully" add_to_report "${report_file}" "

Switchover command succeeded

" # Wait for roles to settle echo "Waiting for roles to settle (30 seconds)..." sleep 30 # Verify new configuration echo "Verifying new configuration..." if verify_post_switchover "${target_db}" "${report_file}"; then finalize_switchover_report "${report_file}" "SUCCESS" return 0 else add_to_report "${report_file}" "

Post-switchover verification failed

" finalize_switchover_report "${report_file}" "FAILED" return 1 fi else echo "Switchover command failed" add_to_report "${report_file}" "

Switchover command failed

" finalize_switchover_report "${report_file}" "FAILED" return 1 fi } ################################################################################ # Function: verify_post_switchover # Description: Verifies configuration after switchover # Parameters: $1 - Expected new primary database name # $2 - Report file path # Returns: 0 if verification passed, 1 if failed ################################################################################ verify_post_switchover() { local expected_primary=$1 local report_file=$2 add_to_report "${report_file}" "

Post-Switchover Verification

" # Get new primary if ! get_primary_database_dgmgrl; then echo "✗ Failed to identify new primary" add_to_report "${report_file}" "

Failed to identify new primary

" return 1 fi echo "New primary database: ${PRIMARY_DB_UNIQUE_NAME}" add_to_report "${report_file}" "

New Primary: ${PRIMARY_DB_UNIQUE_NAME}

" # Verify it matches expected if [[ "${PRIMARY_DB_UNIQUE_NAME}" == "${expected_primary}" ]]; then echo "✓ Primary role assigned correctly to ${expected_primary}" add_to_report "${report_file}" "

✓ Primary role assigned correctly

" else echo "✗ Primary role mismatch - expected ${expected_primary}, got ${PRIMARY_DB_UNIQUE_NAME}" add_to_report "${report_file}" "

✗ Primary role mismatch

" return 1 fi # Check overall status check_dg_status_dgmgrl echo "Configuration status: ${DG_OVERALL_STATUS}" add_to_report "${report_file}" "

Configuration Status: ${DG_OVERALL_STATUS}

" # Get updated standby list get_all_standby_databases_dgmgrl add_to_report "${report_file}" "

Standby Databases:

    " for standby in "${STANDBY_DBS_ARRAY[@]}"; do echo "Standby: ${standby}" add_to_report "${report_file}" "
  • ${standby}
  • " done add_to_report "${report_file}" "
" echo "✓ Post-switchover verification passed" add_to_report "${report_file}" "

✓ Verification passed

" return 0 } ################################################################################ # Function: initialize_switchover_report # Description: Initializes HTML switchover report # Parameters: $1 - Report file path ################################################################################ initialize_switchover_report() { local report_file=$1 cat > "${report_file}" << 'EOF' Data Guard Switchover Report EOF cat >> "${report_file}" << EOF

Data Guard Switchover Report

Configuration: ${DG_CONFIG_NAME}

Generated: $(date '+%Y-%m-%d %H:%M:%S')

EOF } ################################################################################ # Function: add_to_report # Description: Adds content to switchover report # Parameters: $1 - Report file path # $2 - Content to add ################################################################################ add_to_report() { local report_file=$1 local content=$2 echo "${content}" >> "${report_file}" } ################################################################################ # Function: finalize_switchover_report # Description: Finalizes switchover report # Parameters: $1 - Report file path # $2 - Overall status (SUCCESS/FAILED) ################################################################################ finalize_switchover_report() { local report_file=$1 local status=$2 cat >> "${report_file}" << EOF

Overall Status: ${status}

End Time: $(date '+%Y-%m-%d %H:%M:%S')

EOF } ################################################################################ # End of functions_dg_switchover.sh ################################################################################