How To Failover and Flashback a Physical Standby for testing without recreating Database
Failing over and using flashback on a physical standby database for testing without recreating the database involves a structured approach to ensure you can revert to the original state afterward.
This can help for Disaster Recovery testing and we was to have the original state back after the testing.
Pre-requisites:
1) Ensure there is enough space in the Fast Recovery Area (FRA) to hold the flashback logs.
On primary:
SQL> show parameter db_recovery
NAME TYPE VALUE
------------------------------------ ----------- --------------------
db_recovery_file_dest string /u01/install/APPS/data
db_recovery_file_dest_size big integer 150G
df -h /u01/install/APPS/data
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/ocivolume-root 389G 270G 120G 70% /
On Standby:
SQL> show parameter db_recovery
NAME TYPE VALUE
------------------------------------ ----------- --------------------
db_recovery_file_dest string /u01/install/APPS/data
db_recovery_file_dest_size big integer 150G
df -h /u01/install/APPS/data
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/ocivolume-root 389G 261G 129G 68% /
2) Verify synchronization between the primary and standby databases.
On primary:
SQL> SELECT DATABASE_ROLE,OPEN_MODE, PROTECTION_MODE FROM V$DATABASE;
DATABASE_ROLE OPEN_MODE PROTECTION_MODE
---------------- -------------------- --------------------
PRIMARY READ WRITE MAXIMUM PERFORMANCE
SQL> select thread#, max(sequence#) "Last Primary Seq Generated" from v$archived_log val, v$database vdb where val.resetlogs_change# = vdb.resetlogs_change# group by thread# order by 1;
THREAD# Last Primary Seq Generated
---------- --------------------------
1 207
On Standby:
SQL> SELECT DATABASE_ROLE,OPEN_MODE, PROTECTION_MODE FROM V$DATABASE;
DATABASE_ROLE OPEN_MODE PROTECTION_MODE
---------------- -------------------- --------------------
PHYSICAL STANDBY MOUNTED MAXIMUM PERFORMANCE
SQL> select thread#, max(sequence#) "Last Standby Seq Applied" from v$archived_log val, v$database vdb where val.resetlogs_change# = vdb.resetlogs_change# and val.applied in ('YES','IN-MEMORY') group by thread# order by 1;
THREAD# Last Standby Seq Applied
---------- ------------------------
1 207
Create a dummy data on Primary before failover.
-- Connect to your database as the appropriate user
sqlplus / as sysdba
-- Create a dummy table
CREATE TABLE dummy_table (
id NUMBER PRIMARY KEY,
name VARCHAR2(50),
description VARCHAR2(100)
);
-- Insert 5 records into the dummy table
INSERT INTO dummy_table (id, name, description) VALUES (1, 'Record1', 'This is the first record');
INSERT INTO dummy_table (id, name, description) VALUES (2, 'Record2', 'This is the second record');
INSERT INTO dummy_table (id, name, description) VALUES (3, 'Record3', 'This is the third record');
INSERT INTO dummy_table (id, name, description) VALUES (4, 'Record4', 'This is the fourth record');
INSERT INTO dummy_table (id, name, description) VALUES (5, 'Record5', 'This is the fifth record');
-- Commit the changes to make them permanent
COMMIT;
-- Verify the inserted records
SELECT * FROM dummy_table;
--Switch log file and make sure the standby is in sync.
SQL> alter system switch logfile;
System altered.
SQL> /
System altered.
SQL> /
System altered.
SQL> /
System altered.
Check the synchronization now
Both sides it is in sync.
THREAD# Last Standby Seq Applied
---------- ------------------------
1 211
Now before failover lets create a GRP (Guaranteed restore point in Standby Server)
On Standby:
--Check current restore point
select * from v$restore_point;
Please note flashback is off in my environment. It will use FRA space for flashback.
--Stop redo apply process on the Standby database (stop MRP):
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
--Create Restore point
CREATE RESTORE POINT before_failover GUARANTEE FLASHBACK DATABASE;
SQL> select * from v$restore_point;
SCN DATABASE_INCARNATION# GUA STORAGE_SIZE
---------- --------------------- --- ------------
TIME
---------------------------------------------------------------------------
RESTORE_POINT_TIME PRE
--------------------------------------------------------------------------- ---
NAME
--------------------------------------------------------------------------------
PDB CLE PDB_INCARNATION# REP CON_ID
--- --- ---------------- --- ----------
5.9656E+12 7 YES 1048576000
02-NOV-24 05.27.00.000000000 AM
YES
SCN DATABASE_INCARNATION# GUA STORAGE_SIZE
---------- --------------------- --- ------------
TIME
---------------------------------------------------------------------------
RESTORE_POINT_TIME PRE
--------------------------------------------------------------------------- ---
NAME
--------------------------------------------------------------------------------
PDB CLE PDB_INCARNATION# REP CON_ID
--- --- ---------------- --- ----------
BEFORE_FAILOVER
NO NO 0 NO 0
Making the database ready for failover.
On Primary Database
On the primary database, switch logs so the SCN of the restore point will be archived on the physical standby database.
When using standby redo log files, this step is essential to ensure the database can be properly flashed back to the restore point.
SQL> ALTER SYSTEM ARCHIVE LOG CURRENT;
System altered.
SQL> ALTER SYSTEM ARCHIVE LOG CURRENT;
System altered.
SQL> ALTER SYSTEM ARCHIVE LOG CURRENT;
System altered.
SQL> select NAME,DATABASE_ROLE,to_char(CURRENT_SCN),STANDBY_BECAME_PRIMARY_SCN,FLASHBACK_ON from v$database;
NAME DATABASE_ROLE TO_CHAR(CURRENT_SCN)
--------- ---------------- ----------------------------------------
STANDBY_BECAME_PRIMARY_SCN FLASHBACK_ON
-------------------------- ------------------
EBSCDB PRIMARY 5965595145672
0 NO
Primary now on higher sequence and SCN than standby
--Primary
SQL> archive log list
Database log mode Archive Mode
Automatic archival Enabled
Archive destination USE_DB_RECOVERY_FILE_DEST
Oldest online log sequence 213
Next log sequence to archive 215
Current log sequence 215
SQL> select thread#, max(sequence#) "Last Primary Seq Generated" from v$archived_log val, v$database vdb where val.resetlogs_change# = vdb.resetlogs_change# group by thread# order by 1;
THREAD# Last Primary Seq Generated
---------- --------------------------
1 214
--Standby
SQL> select thread#, max(sequence#) "Last Standby Seq Applied" from v$archived_log val, v$database vdb where val.resetlogs_change# = vdb.resetlogs_change# and val.applied in ('YES','IN-MEMORY') group by thread# order by 1;
THREAD# Last Standby Seq Applied
---------- ------------------------
1 211
I will shut abort the primary to replicate a disaster
--on primary
sqlplus '/as sysdba'
SQL> shut abort
ORACLE instance shut down.
--on Standby- Activate Standby for Failover:
Activate the standby database to become the primary.
SQL> ALTER DATABASE ACTIVATE STANDBY DATABASE;
Database altered.
SQL> SELECT DATABASE_ROLE,OPEN_MODE, PROTECTION_MODE FROM V$DATABASE;
DATABASE_ROLE OPEN_MODE PROTECTION_MODE
---------------- -------------------- --------------------
PRIMARY MOUNTED MAXIMUM PERFORMANCE
SQL> alter database open;
Database altered.
SQL> SELECT DATABASE_ROLE,OPEN_MODE, PROTECTION_MODE FROM V$DATABASE;
DATABASE_ROLE OPEN_MODE PROTECTION_MODE
---------------- -------------------- --------------------
PRIMARY READ WRITE MAXIMUM PERFORMANCE
Lets check our dummy table and add few transaction on new primary site
SELECT * FROM dummy_table;
-- Insert 2 new records into the dummy table
INSERT INTO dummy_table (id, name, description) VALUES (6, 'Record6', 'This is the sixth record');
INSERT INTO dummy_table (id, name, description) VALUES (7, 'Record7', 'This is the seventh record');
commit;
SELECT * FROM dummy_table;
Now we have 7 records in table.
Lets failback and put the system back into original state
Shutdown and Start in Mount Mode:
--The new primary shutdown and start in mount mode
SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP MOUNT;
--Flashback the Database: Flashback the database to the appropriate SCN or a restore point created before the failover.
FLASHBACK DATABASE TO RESTORE POINT BEFORE_FAILOVER;
--Convert the Database Back to a Physical Standby:
SQL> ALTER DATABASE CONVERT TO PHYSICAL STANDBY;
Start the original primary database
--On primary
sqlplus '/as sysdba'
startup
--on standby
Start MRP process
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;
Check sync on both
-- On primary
SQL> SELECT DATABASE_ROLE,OPEN_MODE, PROTECTION_MODE FROM V$DATABASE;
DATABASE_ROLE OPEN_MODE PROTECTION_MODE
---------------- -------------------- --------------------
PRIMARY READ WRITE MAXIMUM PERFORMANCE
SQL> select thread#, max(sequence#) "Last Primary Seq Generated" from v$archived_log val, v$database vdb where val.resetlogs_change# = vdb.resetlogs_change# group by thread# order by 1;
THREAD# Last Primary Seq Generated
---------- --------------------------
1 215
-- On Standby
SQL> select thread#, max(sequence#) "Last Standby Seq Applied" from v$archived_log val, v$database vdb where val.resetlogs_change# = vdb.resetlogs_change# and val.applied in ('YES','IN-MEMORY') group by thread# order by 1;
THREAD# Last Standby Seq Applied
---------- ------------------------
1 211
SQL> SELECT PROCESS,STATUS, THREAD#,SEQUENCE#, BLOCK#, BLOCKS FROM V$MANAGED_STANDBY ;
PROCESS STATUS THREAD# SEQUENCE# BLOCK# BLOCKS
--------- ------------ ---------- ---------- ---------- ----------
ARCH CONNECTED 0 0 0 0
ARCH CONNECTED 0 0 0 0
ARCH CONNECTED 0 0 0 0
ARCH CONNECTED 0 0 0 0
DGRD ALLOCATED 0 0 0 0
DGRD ALLOCATED 0 0 0 0
RFS IDLE 1 0 0 0
RFS IDLE 0 0 0 0
RFS RECEIVING 1 216 70410 1
RFS IDLE 0 0 0 0
RFS IDLE 0 0 0 0
PROCESS STATUS THREAD# SEQUENCE# BLOCK# BLOCKS
--------- ------------ ---------- ---------- ---------- ----------
MRP0 APPLYING_LOG 1 216 70409 2048000
12 rows selected.
SQL> select thread#, max(sequence#) "Last Standby Seq Applied" from v$archived_log val, v$database vdb where val.resetlogs_change# = vdb.resetlogs_change# and val.applied in ('YES','IN-MEMORY') group by thread# order by 1;
THREAD# Last Standby Seq Applied
---------- ------------------------
1 211
SQL> /
THREAD# Last Standby Seq Applied
---------- ------------------------
1 211
SQL> SELECT PROCESS,STATUS, THREAD#,SEQUENCE#, BLOCK#, BLOCKS FROM V$MANAGED_STANDBY ;
PROCESS STATUS THREAD# SEQUENCE# BLOCK# BLOCKS
--------- ------------ ---------- ---------- ---------- ----------
ARCH CONNECTED 0 0 0 0
ARCH CONNECTED 0 0 0 0
ARCH CONNECTED 0 0 0 0
ARCH CONNECTED 0 0 0 0
DGRD ALLOCATED 0 0 0 0
DGRD ALLOCATED 0 0 0 0
RFS IDLE 1 0 0 0
RFS IDLE 0 0 0 0
RFS RECEIVING 1 216 70464 1
RFS IDLE 0 0 0 0
RFS IDLE 0 0 0 0
PROCESS STATUS THREAD# SEQUENCE# BLOCK# BLOCKS
--------- ------------ ---------- ---------- ---------- ----------
MRP0 APPLYING_LOG 1 216 70463 2048000
12 rows selected.
SQL> select thread#, max(sequence#) "Last Standby Seq Applied" from v$archived_log val, v$database vdb where val.resetlogs_change# = vdb.resetlogs_change# and val.applied in ('YES','IN-MEMORY') group by thread# order by 1;
THREAD# Last Standby Seq Applied
---------- ------------------------
1 211
SQL> /
THREAD# Last Standby Seq Applied
---------- ------------------------
1 215
No if you observe the standby will come back in sync after applying the log. Please wait for some time to make then synchronized.
Drop the restore point in Standby which was created before failover.
SQL> drop restore point BEFORE_FAILOVER;
Restore point dropped.
SQL> select * from v$restore_point;
no rows selected
Post a Comment
Post a Comment