Sunday, November 9, 2025

#!/bin/bash ################################################################################ # Oracle 19c Restore Point Management Functions # Description: Functions for managing restore points in RAC/DG environments # 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 control functions (stop_apply_on_standby, start_apply_on_standby, # get_primary_and_standbys_dgmgrl, etc.) are now in functions_common.sh ################################################################################ # Function: create_restore_point_primary # Description: Creates restore point on primary database only # Parameters: $1 - Database name # $2 - SCAN address # $3 - Service name # $4 - Restore point name ################################################################################ create_restore_point_primary() { local db_name=$1 local scan=$2 local service=$3 local rp_name=$4 log_message "INFO" "Creating restore point '${rp_name}' on primary database ${db_name}" # Validate connection validate_database_connection "${db_name}" "${scan}" "${service}" local connect_string="${SYS_USER}/${SYS_PASSWORD}@${scan}/${service} as sysdba" # Create restore point local result=$(${ORACLE_HOME}/bin/sqlplus -S /nolog << EOF connect ${connect_string} set feedback off heading off pagesize 0 whenever sqlerror exit 1 CREATE RESTORE POINT ${rp_name} GUARANTEE FLASHBACK DATABASE; select 'Restore point created successfully' from dual; exit; EOF ) if echo "${result}" | grep -q "successfully"; then log_message "INFO" "Restore point '${rp_name}' created on ${db_name}" echo "✓ Restore point '${rp_name}' created successfully on ${db_name}" return 0 else log_message "ERROR" "Failed to create restore point on ${db_name}" echo "✗ Failed to create restore point: ${result}" return 1 fi } ################################################################################ # Function: create_restore_point_all_dg_members # Description: Creates restore point on all DG members (standby first) # Parameters: $1 - Database name (will auto-detect primary/standbys) # $2 - Restore point name ################################################################################ create_restore_point_all_dg_members() { local db_name=$1 local rp_name=$2 log_message "INFO" "Creating restore point '${rp_name}' on all DG members" # Get DG configuration if ! get_dg_broker_configuration "${db_name}"; then log_message "ERROR" "Failed to get DG Broker configuration" echo "ERROR: Not part of Data Guard configuration" return 1 fi # Get primary and standbys with connection info if ! get_primary_and_standbys_dgmgrl; then log_message "ERROR" "Failed to get DG topology" return 1 fi local all_success=0 # Parse primary info IFS='|' read -r primary_db primary_conn <<< "${PRIMARY_DB}" IFS='|' read -r primary_scan primary_service <<< "${primary_conn}" echo "" echo "===================================================================" echo " Creating Restore Point: ${rp_name}" echo " on all Data Guard members" echo "===================================================================" echo "" # Step 1: Stop apply on all standbys if [[ ${#STANDBY_DBS_ARRAY[@]} -gt 0 ]]; then echo "Step 1: Stopping MRP on standby databases..." for standby_entry in "${STANDBY_DBS_ARRAY[@]}"; do IFS='|' read -r standby_db standby_conn <<< "${standby_entry}" IFS='|' read -r standby_scan standby_service <<< "${standby_conn}" echo " Stopping MRP on ${standby_db}..." if stop_apply_on_standby "${standby_db}"; then echo " ✓ MRP stopped on ${standby_db}" else echo " ✗ Failed to stop MRP on ${standby_db}" all_success=1 fi done echo "" fi # Step 2: Create restore point on all standbys first if [[ ${#STANDBY_DBS_ARRAY[@]} -gt 0 ]]; then echo "Step 2: Creating restore point on standby databases..." for standby_entry in "${STANDBY_DBS_ARRAY[@]}"; do IFS='|' read -r standby_db standby_conn <<< "${standby_entry}" IFS='|' read -r standby_scan standby_service <<< "${standby_conn}" echo " Creating restore point on ${standby_db}..." if create_restore_point_primary "${standby_db}" "${standby_scan}" "${standby_service}" "${rp_name}"; then echo " ✓ Restore point created on ${standby_db}" else echo " ✗ Failed to create restore point on ${standby_db}" all_success=1 fi done echo "" fi # Step 3: Create restore point on primary echo "Step 3: Creating restore point on primary database..." echo " Creating restore point on ${primary_db}..." if create_restore_point_primary "${primary_db}" "${primary_scan}" "${primary_service}" "${rp_name}"; then echo " ✓ Restore point created on ${primary_db}" else echo " ✗ Failed to create restore point on ${primary_db}" all_success=1 fi echo "" # Step 4: Restart apply on all standbys if [[ ${#STANDBY_DBS_ARRAY[@]} -gt 0 ]]; then echo "Step 4: Restarting MRP on standby databases..." for standby_entry in "${STANDBY_DBS_ARRAY[@]}"; do IFS='|' read -r standby_db standby_conn <<< "${standby_entry}" echo " Starting MRP on ${standby_db}..." if start_apply_on_standby "${standby_db}"; then echo " ✓ MRP started on ${standby_db}" else echo " ✗ Failed to start MRP on ${standby_db}" all_success=1 fi done echo "" fi echo "===================================================================" if [[ ${all_success} -eq 0 ]]; then echo " Restore Point Creation: SUCCESS" log_message "INFO" "Restore point '${rp_name}' created on all DG members" else echo " Restore Point Creation: COMPLETED WITH ERRORS" log_message "WARN" "Restore point creation had some failures" fi echo "===================================================================" return ${all_success} } ################################################################################ # Function: list_restore_points # Description: Lists all restore points on a database # Parameters: $1 - Database name # $2 - SCAN address # $3 - Service name ################################################################################ list_restore_points() { local db_name=$1 local scan=$2 local service=$3 log_message "INFO" "Listing restore points for ${db_name}" # Validate connection validate_database_connection "${db_name}" "${scan}" "${service}" local connect_string="${SYS_USER}/${SYS_PASSWORD}@${scan}/${service} as sysdba" echo "" echo "===================================================================" echo " Restore Points on ${db_name}" echo "===================================================================" ${ORACLE_HOME}/bin/sqlplus -S /nolog << EOF connect ${connect_string} set linesize 200 pagesize 100 column name format a30 column scn format 999999999999999 column time format a30 column guarantee_flashback_database format a10 heading "GUARANTEED" column storage_size format 999,999,999,999 heading "SIZE (BYTES)" select name, scn, to_char(time, 'YYYY-MM-DD HH24:MI:SS') as time, guarantee_flashback_database, storage_size from v\$restore_point order by time desc; exit; EOF echo "===================================================================" return 0 } ################################################################################ # Function: drop_restore_point_primary # Description: Drops restore point from primary database # Parameters: $1 - Database name # $2 - SCAN address # $3 - Service name # $4 - Restore point name ################################################################################ drop_restore_point_primary() { local db_name=$1 local scan=$2 local service=$3 local rp_name=$4 log_message "INFO" "Dropping restore point '${rp_name}' from ${db_name}" # Validate connection validate_database_connection "${db_name}" "${scan}" "${service}" local connect_string="${SYS_USER}/${SYS_PASSWORD}@${scan}/${service} as sysdba" # Drop restore point local result=$(${ORACLE_HOME}/bin/sqlplus -S /nolog << EOF connect ${connect_string} set feedback off heading off pagesize 0 whenever sqlerror exit 1 DROP RESTORE POINT ${rp_name}; select 'Restore point dropped successfully' from dual; exit; EOF ) if echo "${result}" | grep -q "successfully"; then log_message "INFO" "Restore point '${rp_name}' dropped from ${db_name}" echo "✓ Restore point '${rp_name}' dropped successfully from ${db_name}" return 0 else log_message "ERROR" "Failed to drop restore point from ${db_name}" echo "✗ Failed to drop restore point: ${result}" return 1 fi } ################################################################################ # Function: drop_restore_point_all_dg_members # Description: Drops restore point from all DG members # Parameters: $1 - Database name (will auto-detect primary/standbys) # $2 - Restore point name ################################################################################ drop_restore_point_all_dg_members() { local db_name=$1 local rp_name=$2 log_message "INFO" "Dropping restore point '${rp_name}' from all DG members" # Get DG configuration if ! get_dg_broker_configuration "${db_name}"; then log_message "ERROR" "Failed to get DG Broker configuration" echo "ERROR: Not part of Data Guard configuration" return 1 fi # Get primary and standbys with connection info if ! get_primary_and_standbys_dgmgrl; then log_message "ERROR" "Failed to get DG topology" return 1 fi local all_success=0 # Parse primary info IFS='|' read -r primary_db primary_conn <<< "${PRIMARY_DB}" IFS='|' read -r primary_scan primary_service <<< "${primary_conn}" echo "" echo "===================================================================" echo " Dropping Restore Point: ${rp_name}" echo " from all Data Guard members" echo "===================================================================" echo "" # Drop from primary first echo "Dropping restore point from primary database..." echo " Dropping from ${primary_db}..." if drop_restore_point_primary "${primary_db}" "${primary_scan}" "${primary_service}" "${rp_name}"; then echo " ✓ Restore point dropped from ${primary_db}" else echo " ✗ Failed to drop restore point from ${primary_db}" all_success=1 fi echo "" # Drop from all standbys if [[ ${#STANDBY_DBS_ARRAY[@]} -gt 0 ]]; then echo "Dropping restore point from standby databases..." for standby_entry in "${STANDBY_DBS_ARRAY[@]}"; do IFS='|' read -r standby_db standby_conn <<< "${standby_entry}" IFS='|' read -r standby_scan standby_service <<< "${standby_conn}" echo " Dropping from ${standby_db}..." if drop_restore_point_primary "${standby_db}" "${standby_scan}" "${standby_service}" "${rp_name}"; then echo " ✓ Restore point dropped from ${standby_db}" else echo " ✗ Failed to drop restore point from ${standby_db}" all_success=1 fi done echo "" fi echo "===================================================================" if [[ ${all_success} -eq 0 ]]; then echo " Restore Point Deletion: SUCCESS" log_message "INFO" "Restore point '${rp_name}' dropped from all DG members" else echo " Restore Point Deletion: COMPLETED WITH ERRORS" log_message "WARN" "Restore point deletion had some failures" fi echo "===================================================================" return ${all_success} } ################################################################################ # End of functions_restore_point.sh ################################################################################