Shell script to convert physical standby database into snapshot standby and vice versa

 

Today I will show a scenario where a customer had a requirement to refresh their snapshot standby database. The setup was 1 primary database and 2 physical standby databases among which one standby database was always kept in physical standby mode but the other one was used by the developer and a daily refresh was the requirement.

Since they wanted to convert snapshot standby into physical standby for sync and later convert it back to snapshot standby I prepared two shell script to perform the entire activity.

 

·       Shell script to convert physical standby database into snapshot standby database

#!/bin/bash


 # Set environment variables

export ORACLE_HOME=/u01/oracle/19.3.0

export ORACLE_SID=PROD

export PATH=$ORACLE_HOME/bin:$PATH

 

# Define database names

PRIMARY_DB_NAME=PROD

STANDBY_DB_NAME=SBDB

 

# Define log file path

rm $LOG_FILE

LOG_FILE=/u01/snapshot_convert_logfile.log

 

# Define maximum number of retries

MAX_RETRIES=2

 

# Function to log messages to log file

log() {

  echo "$(date +'%Y-%m-%d %H:%M:%S') $1" >> $LOG_FILE

}

 

# Function to perform conversion

perform_conversion() {

  log "Performing conversion of $STANDBY_DB_NAME to snapshot standby..."

  dgmgrl <<EOF

  connect /

  convert database $STANDBY_DB_NAME to snapshot standby;

EOF

} >> $LOG_FILE

# Retry loop

retries=0

while [ $retries -lt $MAX_RETRIES ]; do

  perform_conversion

  if grep -q "ORA-" $LOG_FILE; then

    log "Error occurred during conversion. Retrying..."

    ((retries++))

    sleep 5

  else

    log "Conversion completed successfully. Standby database is now a snapshot standby."

    break

  fi

done

 

# Check for maximum retries

if [ $retries -eq $MAX_RETRIES ]; then

  log "Maximum retries reached. Conversion failed. Please check the log for details."

fi

 

 

·       Shell script to convert snapshot standby database into physical standby database

#!/bin/bash

 

# Set environment variables

export ORACLE_HOME=/u01/oracle/19.3.0

export ORACLE_SID=PROD

export PATH=$ORACLE_HOME/bin:$PATH

 

# Define database names

PRIMARY_DB_NAME=PROD

STANDBY_DB_NAME=SBDB

 

# Define log file path

rm $LOG_FILE

LOG_FILE=/u01/physical_convert_logfile.log

 

# Define maximum number of retries

MAX_RETRIES=2

 

# Function to log messages to log file

log() {

  echo "$(date +'%Y-%m-%d %H:%M:%S') $1" >> $LOG_FILE

}

 

# Function to perform conversion

perform_conversion() {

  log "Performing conversion of $STANDBY_DB_NAME to physical standby..."

dgmgrl sys/Prodpassword@prod<<EOF

convert database $STANDBY_DB_NAME to physical standby;

EOF

} >> $LOG_FILE

# Retry loop

retries=0

while [ $retries -lt $MAX_RETRIES ]; do

  perform_conversion

  if grep -q "ORA-" $LOG_FILE; then

    log "Error occurred during conversion. Retrying..."

    ((retries++))

    sleep 5

  else

    log "Conversion completed successfully. Standby database is now a physical standby."

    break

  fi

done

 

# Check for maximum retries

if [ $retries -eq $MAX_RETRIES ]; then

  log "Maximum retries reached. Conversion failed. Please check the log for details."

fi

 

Once the snapshot standby is converted to physical standby, give it time to synchronize with primary database.

How to purge dba_recyclebin older than 30 days in oracle database 19c

 In the following post I will show you how to purge dba_recyclebin older than X number of days.

For e.g I want to purge recyclebin data older than 30 days

 

Oracle recommends not to use delete statement on dba_recyclebin as this doesn’t allow to delete data older than 7 days

 

SQL> Delete from dba_recylebin where droptime <sysdate -30;

ERROR at line 1:

ORA-01752: cannot delete from view without exactly one key-preserved table

 

 Rather run the following script to generate a select sql and execute it to purge dba_recyclebin

SQL>set head off

SQL>spool purge.sql

SQL> select 'purge table '||owner||'."'||OBJECT_NAME||'";'

from dba_recyclebin where type='TABLE'

and to_date(droptime,'YYYY-MM-DD:HH24:MI:SS')<sysdate-30;

SQL>spool off;

 

This will create a sql with output like below

purge table JHO."BIN$xXn88xp3GejgU/GEF6wbcA==$0";                                                                                                       

purge table JHO."BIN$xwxOc+5mLK7gU/GEF6yizA==$0";                                                                                                      

purge table JHO."BIN$w4MOItowfC/gU/GEF6xrHA==$0";                                                                                                       

purge table JHO."BIN$x4UA4M5zTZTgU/OEF6xB8w==$0"; 

 

Execute purge.sql file to purge all the tables for older than 30 days in recylebin

SQL>@purge.sql

Table purged.

Table purged.

Table purged.

 

 

Handy Oracle Data guard Broker Commands Part-II

Following command will validate the configuration of the specified database.

DGMGRL> validate database 'db_name';

DGMGRL> validate database proddr;

 

  Database Role:     Physical standby database

  Primary Database:  prod

 

  Ready for Switchover:  Yes

  Ready for Failover:    Yes (Primary Running)

 

  Flashback Database Status:

    prod  :  On

    proddr:  Off

 

  Managed by Clusterware:

    prod  :  NO

    proddr:  NO

    Validating static connect identifier for the primary database prod...

    The static connect identifier allows for a connection to database "prod".

 

DGMGRL>

 

 

Following command will display the current Fast-Start Failover configuration.

DGMGRL> show fast_start failover

 

Fast-Start Failover:  Disabled

 

  Protection Mode:    MaxPerformance

  Lag Limit:          30 seconds

 

  Threshold:          30 seconds

  Active Target:      (none)

  Potential Targets:  (none)

  Observer:           (none)

  Shutdown Primary:   TRUE

  Auto-reinstate:     TRUE

  Observer Reconnect: (none)

  Observer Override:  FALSE

 

Configurable Failover Conditions

  Health Conditions:

    Corrupted Controlfile          YES

    Corrupted Dictionary           YES

    Inaccessible Logfile            NO

    Stuck Archiver                  NO

    Datafile Write Errors          YES

 

  Oracle Error Conditions:

    (none)

 

 

 

The following command is used to convert database to snapshot standby.

DGMGRL> convert database 'db_name' to snapshot standby;

DGMGRL> convert database sbdb to Snapshot standby;

Converting database "sbdb" to a Snapshot Standby database, please wait...

Database "sbdb" converted successfully

 

The following command is used to convert database to physical standby.

DGMGRL> convert database 'db_name' to physical standby;

 

DGMGRL> convert database sbdb to Physical standby;

Converting database "sbdb" to a Physical Standby database, please wait...

Operation requires shut down of instance "PROD" on database "sbdb"

Shutting down instance "PROD"...

Connected to "SBDB"

Database closed.

Database dismounted.

ORACLE instance shut down.

Operation requires start up of instance "PROD" on database "sbdb"

Starting instance "PROD"...

Connected to an idle instance.

ORACLE instance started.

Connected to "SBDB"

Database mounted.

Connected to "SBDB"

Database "sbdb" converted successfully

 

The following command validates static connect identifier for given db_name

DGMGRL> VALIDATE STATIC CONNECT IDENTIFIER FOR SBDB;

Oracle Clusterware is not configured on database "sbdb".

Connecting to database "sbdb" using static connect identifier "(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=az-psdb1)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=SBDB_DGMGRL)(INSTANCE_NAME=PROD)(SERVER=DEDICATED)(STATIC_SERVICE=TRUE)))" ...

Succeeded.

The static connect identifier allows for a connection to database "sbdb".

 

DGMGRL>

 

Execute sql statement from DGMGRL prompt. Select command doesn’t work from this prompt.

 

DGMGRL> sql "alter system switch logfile"

Succeeded.

DGMGRL>

 

 

Shell script to purge diagnostic files using ADRCI utility

 Using following shell script we can easily purge diagnostic files such as trace, alert, cdump etc.

$ vi /home/oracle/adrci_purge.sh

#!/usr/bin/ksh

#

#

#

# Description

# Shell script to  purge ADR contents using ADRCI utility.

#

###

 

LOCKFILE=/tmp/adrci_purge_.lck

 

###

 

######

# Start Of Functions

#

# tidyup . common fuction called if error has occured

tidyup () {

        rm -f ${LOCKFILE}

        echo "ERROR: Purge aborted at `date` with exit code ${ERR}"

        exit ${ERR}

}

 

######

# End Of Functions

 

### Main Program

 

# Check user is oracle

USERID=`/usr/bin/id -u -nr`

if [ $? -ne 0 ]

then

        echo "ERROR: unable to determine uid"

        exit 99

fi

#if [ "${USERID}" != "oracle" ]

#then

#        echo "ERROR: This script must be run as oracle"

#        exit 98

#fi

 

echo "INFO: Purge started at `date`"

 

# Check if lockfile exists

if [ -f ${LOCKFILE} ]

then

        echo "ERROR: Lock file already exists"

        echo "       Purge already active or incorrectly terminated"

        echo "       If you are sure tidy isn.t active, please remove "

        echo "       ${LOCKFILE}"

            #rm -f ${LOCKFILE}

        exit 97

fi

 

# Create lock file

touch ${LOCKFILE} 2>/dev/null

if [ $? -ne 0 ]

then

        echo "ERROR: Unable to create lock file"

        exit 96

fi

 

# Purge ADR contents

 

echo "INFO: adrci purge started at `date`"

 

 

ALL_DATABASES=`cat /etc/oratab|grep -v "^#"|  grep -Eo '^[^ ]+' |cut -f1 -d: -s`

 

for DB in $ALL_DATABASES

do

   unset  TWO_TASK

   export ORACLE_SID=$DB

   export ORACLE_HOME=`grep "^${DB}:" /etc/oratab|cut -d: -f2 -s`

   export PATH=$ORACLE_HOME/bin:$PATH

   echo "---> Database $ORACLE_SID, using home $ORACLE_HOME"

 

  $ORACLE_HOME/bin/adrci exec="set base /u01/oracle;show homes"|grep -v : | while read file_line

  do

  echo "INFO: adrci purging diagnostic destination " $file_line

 

  echo "INFO: purging ALERT older than 60 days .."

  $ORACLE_HOME/bin/adrci exec="set base /u01/oracle;set homepath $file_line;purge -age 43200 -type ALERT"

 

  echo "INFO: purging INCIDENT older than 60 days .."

  $ORACLE_HOME/bin/adrci exec="set base /u01/oracle;set homepath $file_line;purge -age 43200 -type INCIDENT"

 

  echo "INFO: purging TRACE older than 60 days .."

  $ORACLE_HOME/bin/adrci exec="set base /u01/oracle;set homepath $file_line;purge -age 43200 -type TRACE"

 

  echo "INFO: purging CDUMP older than 60 days .."

  $ORACLE_HOME/bin/adrci exec="set base /u01/oracle;set homepath $file_line;purge -age 43200 -type CDUMP"

 

  echo "INFO: purging HM older than 60 days .."

  $ORACLE_HOME/bin/adrci exec="set base /u01/oracle;set homepath $file_line;purge -age 43200 -type HM"

 

  echo ""

  echo ""

 

done

 

done

 

 

# All completed

rm -f ${LOCKFILE}

echo "SUCC: Purge completed successfully at `date`"

exit 0



# crontab -e

0 1 * * * /orabackup/scripts/adrci_purge.sh