#!/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
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
################################################################################