You are on page 1of 26

ENV Details Primary Side Standby Side

DB Unique Name DB19_iad2zj DB19_iad27v


DB Name DB19 DB19
DB Role
Server IP 158.101.105.62 150.136.10.195
DB Version Oracle Database 19c Oracle Database 19c
OS Version Red Hat Enterprise Linux Server Red Hat Enterprise Linux Server
release 7.9 release 7.9

/etc/hosts to setup the name resolution on both side


# source
127.0.0.1 localhost localhost.localdomain localhost4
localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.100.67 src.publicsn.dblabvcn.oraclevcn.com src
192.168.100.67 src-scan.publicsn.dblabvcn.oraclevcn.com src-scan

######################## Target Host Details #####################

192.168.100.118 tgt.publicsn.dblabvcn.oraclevcn.com tgt


192.168.100.118 tgt-scan.publicsn.dblabvcn.oraclevcn.com tgt-scan

#Target

[root@tgt ~]# vi /etc/hosts


127.0.0.1 localhost localhost.localdomain localhost4
localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.100.118 tgt.publicsn.dblabvcn.oraclevcn.com tgt
192.168.16.18 tgt-priv.publicsn.dblabvcn.oraclevcn.com tgt-priv
192.168.100.118 tgt-vip.publicsn.dblabvcn.oraclevcn.com tgt-vip
192.168.100.118 tgt-scan.publicsn.dblabvcn.oraclevcn.com tgt-scan

################## Source Details

192.168.100.67 src.publicsn.dblabvcn.oraclevcn.com src


192.168.100.67 src-scan.publicsn.dblabvcn.oraclevcn.com src-scan

ENV file
Source
[oracle@src ~]$ cat DB19_src.env
PATH=/u01/app/oracle/product/19.0.0.0/dbhome_1/bin:/u01/app/oracle/
product/19.0.0.0/dbhome_1/OPatch:$PATH; export PATH
ORACLE_UNQNAME=DB19_iad2zj; export ORACLE_UNQNAME
ORACLE_SID=DB19; export ORACLE_SID
ORACLE_HOSTNAME=src.publicsn.dblabvcn.oraclevcn.com; export
ORACLE_HOSTNAME
LD_LIBRARY_PATH=/u01/app/oracle/product/19.0.0.0/dbhome_1/lib; export
LD_LIBRARY_PATH
ORACLE_BASE=/u01/app/oracle; export ORACLE_BASE
OH=/u01/app/oracle/product/19.0.0.0/dbhome_1; export OH
ORACLE_HOME=/u01/app/oracle/product/19.0.0.0/dbhome_1; export
ORACLE_HOME
TNS_ADMIN=/u01/app/oracle/product/19.0.0.0/dbhome_1/network/admin;
export TNS_ADMIN
[oracle@src ~]$

Target

[oracle@tgt ~]$ cat DB19_tgt.env


PATH=/u01/app/oracle/product/19.0.0.0/dbhome_1/bin:/u01/app/oracle/
product/19.0.0.0/dbhome_1/OPatch:$PATH; export PATH
ORACLE_UNQNAME=DB19_iad27v; export ORACLE_UNQNAME
ORACLE_SID=DB19; export ORACLE_SID
ORACLE_HOSTNAME=tgt.publicsn.dblabvcn.oraclevcn.com; export
ORACLE_HOSTNAME
LD_LIBRARY_PATH=/u01/app/oracle/product/19.0.0.0/dbhome_1/lib; export
LD_LIBRARY_PATH
ORACLE_BASE=/u01/app/oracle; export ORACLE_BASE
OH=/u01/app/oracle/product/19.0.0.0/dbhome_1; export OH
ORACLE_HOME=/u01/app/oracle/product/19.0.0.0/dbhome_1; export
ORACLE_HOME
TNS_ADMIN=/u01/app/oracle/product/19.0.0.0/dbhome_1/network/admin;
export TNS_ADMIN
[oracle@tgt ~]$

Primary Server side Configurations:-


Step1:- Enable Archivelog mode and force logging mode

sqlplus / as sysdba
select log_mode from v$database ;

alter system set log_archive_dest_1 =


'LOCATION=USE_DB_RECOVERY_FILE_DEST' scope=both;
shutdown immediate
startup mount

SQL> select name,open_mode from v$database ;

NAME OPEN_MODE
--------- --------------------
DB19 MOUNTED

alter database archivelog;


alter database open;
alter system switch logfile;
select name from v$archived_log;

SQL> ALTER DATABASE FORCE LOGGING;

SQL> select name,OPEN_MODE,LOG_MODE,FORCE_LOGGING from v$database ;

NAME OPEN_MODE LOG_MODE FORCE_LOGGING


--------- -------------------- ------------ ---------------------------------------
DB19 MOUNTED ARCHIVELOG YES

SQL> alter database open;

Database altered.

SQL>
Step2:-Adding Redologfile for standby database

Check redo log size

SQL> select group#, thread#, bytes/1024/1024 mb from v$log;

GROUP# THREAD# MB
---------- ---------- ----------
1 1 1024
2 1 1024
3 1 1024

SQL> select thread#, instance from v$thread ;

THREAD# INSTANCE
---------- ----------------

1 DB19

Create standby redo logs


===========================

Create standby redo logs on the primary database (in case of


switchovers). The standby redo logs should be at least as big as the
largest online redo log and there should be one extra group per thread
compared the online redo logs.

alter database add standby logfile thread 1 size 1024m;


alter database add standby logfile thread 1 size 1024m;
alter database add standby logfile thread 1 size 1024m;
alter database add standby logfile thread 1 size 1024m;

SQL> alter database add standby logfile thread 1 size 1024m ;

Database altered.

SQL> alter database add standby logfile thread 1 size 1024m ;


Database altered.

SQL> alter database add standby logfile thread 1 size 1024m ;

Database altered.

SQL>

Check the standby redo logs

SQL> select group#, thread#, sequence#, bytes/1024/1024 mb, archived,


status from v$standby_log;

GROUP# THREAD# SEQUENCE# MB ARC STATUS


---------- ---------- ---------- ---------- --- ----------
4 1 0 1024 YES UNASSIGNED
5 1 0 1024 YES UNASSIGNED
6 1 0 1024 YES UNASSIGNED
7 1 0 1024 YES UNASSIGNED

SQL> select member from v$logfile where type = 'STANDBY';


MEMBER
-----------------------------------------------------------

+RECO/DB19_IAD2ZJ/ONLINELOG/group_4.264.1100024425
+RECO/DB19_IAD2ZJ/ONLINELOG/group_5.265.1100024443
+RECO/DB19_IAD2ZJ/ONLINELOG/group_6.266.1100024453
+RECO/DB19_IAD2ZJ/ONLINELOG/group_7.270.1100156995

Check db_unique_name
SQL> show parameter db_unique_name

NAME TYPE VALUE


------------------------------------ ----------- -------------
db_unique_name string DB19_iad2zj

Set log_archive_config

alter system set


log_archive_config='DG_CONFIG=(DB19_iad2zj,DB19_iad27v)' scope=both;

SQL> ALTER SYSTEM SET


log_archive_dest_1=’location=use_db_recovery_file_dest
valid_for=(all_logfiles,all_roles) db_unique_name= DB19_iad2zj’
SCOPE=both;
System altered.

Set log_archive_dest_2

alter system set log_archive_dest_2='SERVICE= DB19_TG ASYNC


VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=DB19_iad27v'
scope=both;

SQL> alter system set log_archive_dest_2='SERVICE= DB19_TG ASYNC


VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=DB19_iad27v'
scope=both;

System altered.

SQL>

Set fal_server

SQL> show parameter fal_server ;

NAME TYPE VALUE


------------------------------------ -----------
------------------------------
fal_server string
SQL> alter system set fal_server ='DB19_iad27v' scope=both;

System altered.

SQL> alter system set log_archive_dest_state_2=enable;


System altered.
SQL> alter system set log_archive_dest_state_1=enable;
System altered.
SQL> alter system set remote_login_passwordfile=exclusive
scope=spfile;
System altered.

fal_client is not needed anymore in Oracle 19c.

Set standby_file_management

show parameter standby_file_management


alter system set standby_file_management='AUTO' scope=both;
SQL> show parameter standby_file_management

NAME TYPE VALUE


------------------------------------ ----------- ----------
standby_file_management string MANUAL

SQL> alter system set standby_file_management='AUTO' scope=both;

System altered.

Check the password file.

How do you know the name and location of the password file for 12c
Database?

Use the “srvctl” utility to the database configuration as follows:


[oracle@src ~]$ srvctl config database -d $ORACLE_UNQNAME
Database unique name: DB19_iad2zj
Database name: DB19
Oracle home: /u01/app/oracle/product/19.0.0.0/dbhome_1
Oracle user: oracle
Spfile: +DATA/DB19_IAD2ZJ/PARAMETERFILE/spfile.267.1099502851
Password file:
Domain: publicsn.dblabvcn.oraclevcn.com
Start options: open
Stop options: immediate
Database role: PRIMARY
Management policy: AUTOMATIC
Server pools:
Disk Groups: RECO,DATA
Mount point paths:
Services:
Type: SINGLE
OSDBA group: dba
OSOPER group: dbaoper
Database instance: DB19
Configured nodes: src
CSS critical: no
CPU count: 0
Memory target: 0
Maximum memory: 0
Default network number for database services:
Database is administrator managed
[oracle@src ~]$

OR

[grid@src ~]$ crsctl stat res ora.db19_iad2zj.db -f | grep PWFILE


PWFILE=
[grid@src ~]$

OR

ASMCMD> pwget --dbuniquename db19_iad2zj


Password file location has not been set for DB instance
ASMCMD>

How can I create a new password file on the ASM?


We have two ways, either by using the pwcreate/asmcmd command or by
using the normal orapwd utility which is updated to support ASM

orapwd file='+DATA' password=WelC0me_123# dbuniquename=db19_iad2zj

[oracle@src ~]$ orapwd file='+DATA' password=WelC0me_123#


dbuniquename=db19_iad2zj
[oracle@src ~]$ srvctl config database -d $ORACLE_UNQNAME
Database unique name: DB19_iad2zj
Database name: DB19
Oracle home: /u01/app/oracle/product/19.0.0.0/dbhome_1
Oracle user: oracle
Spfile: +DATA/DB19_IAD2ZJ/PARAMETERFILE/spfile.267.1099502851
Password file:
+DATA/DB19_IAD2ZJ/PASSWORD/pwddb19_iad2zj.271.1100137729
Domain: publicsn.dblabvcn.oraclevcn.com
Start options: open
Stop options: immediate
Database role: PRIMARY
Management policy: AUTOMATIC
Server pools:
Disk Groups: RECO,DATA
Mount point paths:
Services:
Type: SINGLE
OSDBA group: dba
OSOPER group: dbaoper
Database instance: DB19
Configured nodes: src
CSS critical: no
CPU count: 0
Memory target: 0
Maximum memory: 0
Default network number for database services:
Database is administrator managed
[oracle@src ~]$

How to copy the shared ASM Password file to the Standby Server?

In the Data Guard environment, you have to copy the primary database
password file to the standby server.
Note that it is not sufficient to create a password file on the
standby with the same sys password.
The steps are as follows:

Copy the primary ASM PWD file from ASM to a temp location in filesystem (on the primary
node)

From the Primary Side:

ASMCMD> pwcopy
+DATA/DB19_IAD2ZJ/PASSWORD/pwddb19_iad2zj.271.1100137729 /tmp
copying +DATA/DB19_IAD2ZJ/PASSWORD/pwddb19_iad2zj.271.1100137729 ->
/tmp/pwddb19_iad2zj.271.1100137729
ASMCMD>

Using winscp or scp copy the password file to target

Add to tnsnames.ora

##TARGET
DB19_TG=
(DESCRIPTION=
(ADDRESS=
(PROTOCOL=TCP)
(HOST=192.168.100.118)
(PORT=1521))
(CONNECT_DATA=
(SERVER=DEDICATED)
(SERVICE_NAME=DB19_iad27v.publicsn.dblabvcn.oraclevcn.com)))

##SOURCE
DB19_SRC =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.100.67)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = DB19_iad2zj.publicsn.dblabvcn.oraclevcn.com)
)
)

tnsping DB19_SRC
tnsping DB19_TG

Test connectivity with SQLplus and RMAN - SOURCE AND TARGET


-- FROM SQLplus
sqlplus /nolog
connect sys/WelC0me_123#@DB19_SRC as sysdba
select instance_name, host_name from v$instance;

connect sys/WelC0me_123#@DB19_TG as sysdba


select instance_name, host_name from v$instance;

rman
connect target sys/WelC0me_123#@DB19_SRC --Source
connect auxiliary sys/WelC0me_123#@DB19_TG -- Target

Restart primary

2. Prepare the standby database

Create an init file with just the db_name.

Remember, the db_name will be the same in both the primary and the standby
database.

Only the db_unique_name will be different.

Copy the password file from the primary server to the standby server.

ASMCMD> mkdir PASSWORD


ASMCMD> cd PASSWORD

ASMCMD> pwcopy /tmp/pwddb19_iad2zj.271.1100137729


+DATA/DB19_IAD27V/PASSWORD/pwddb19_DB19_IAD27V
copying /tmp/pwddb19_iad2zj.271.1100137729 ->
+DATA/DB19_IAD27V/PASSWORD/pwddb19_DB19_IAD27V
ASMCMD> ls
pwddb19_db19_iad27v
ASMCMD>

[oracle@tgt ~]$ srvctl modify database -db $ORACLE_UNQNAME -pwfile


+DATA/DB19_IAD27V/PASSWORD/pwddb19_db19_iad27v
[oracle@tgt ~]$

[oracle@tgt ~]$ srvctl config database -d $ORACLE_UNQNAME


Database unique name: DB19_iad27v
Database name: DB19
Oracle home: /u01/app/oracle/product/19.0.0.0/dbhome_1
Oracle user: oracle
Spfile: +DATA/DB19_IAD27V/PARAMETERFILE/spfile.267.1099502915
Password file: +DATA/DB19_IAD27V/PASSWORD/pwddb19_db19_iad27v
Domain: publicsn.dblabvcn.oraclevcn.com
Start options: open
Stop options: immediate
Database role: PRIMARY
Management policy: AUTOMATIC
Server pools:
Disk Groups: RECO,DATA
Mount point paths:
Services:
Type: SINGLE
OSDBA group: dba
OSOPER group: dbaoper
Database instance: DB19
Configured nodes: tgt
CSS critical: no
CPU count: 0
Memory target: 0
Maximum memory: 0
Default network number for database services:
Database is administrator managed
[oracle@tgt ~]$

Copy the tnsnames.ora file

##TARGET
DB19_TG=
(DESCRIPTION=
(ADDRESS=
(PROTOCOL=TCP)
(HOST=192.168.100.118)
(PORT=1521))
(CONNECT_DATA=
(SERVER=DEDICATED)
(SERVICE_NAME=DB19_iad27v.publicsn.dblabvcn.oraclevcn.com)))

##SOURCE
DB19_SRC =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.100.67)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = DB19_iad2zj.publicsn.dblabvcn.oraclevcn.com)
)
)

Make sure you have a static listener in the new server (I mean, where
will be the new standby). Also, this is very important because the
duplicate stop and start the new instance remotely, start of the
instance remotely is just possible when using static listener

You can use the following example in the listener.ora file. Just
change the value with your environment values.

DON’T FORGOT! if your standby will be a RAC environment, you need to


use the VIP address of one the servers where the instance is, not the
SCAN. The restore must be made just with one instance started, after
the restore you can configure (add) the another instance manually.

# listener.ora Network Configuration File:


/u01/app/19.0.0.0/grid/network/admin/listener.ora
# Generated by Oracle configuration tools.

SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC = (GLOBAL_DBNAME =
DB19_iad27v.publicsn.dblabvcn.oraclevcn.com)
(ORACLE_HOME =
/u01/app/oracle/product/19.0.0.0/dbhome_1)
(SID_NAME = DB19)
)
)
NOTE: GLOBAL_DBNAME = service name

I am using SID_LIST_LISTENER because my listener name is just


LISTENER. The correct is SID_LIST_YOUR_LISTENER_NAME. Also, I like to
use SID_LIST_LISTENER_NAME because I can create more services (a list
of fixed services). It can use multiples $ORACLE_HOME.

For example, if my server has three $ORACLE_HOME, 11.2, 12.2 and 19.3
and I am using the listener.ora in the grid_home. Could be something
like it:

SID_LIST_LISTENER_NAME =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = service_one)
(ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1 )
(SID_NAME = inst_1)
)
(SID_DESC =
(GLOBAL_DBNAME = service_two)
(ORACLE_HOME = /u01/app/oracle/product/12.2.0/dbhome_1 )
(SID_NAME = inst_2)
)
(SID_DESC =
(SID_NAME = service_three)
(ORACLE_HOME = /u01/app/oracle/product/19.3.0/dbhome_1 )
(SID_NAME = inst_3)
)
)

------------------------------------- Reload the listener

[grid@tgt admin]$ lsnrctl reload

[grid@tgt admin]$ lsnrctl status

LSNRCTL for Linux: Version 19.0.0.0.0 - Production on 24-MAR-2022 04:58:38

Copyright (c) 1991, 2021, Oracle. All rights reserved.

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER)))
STATUS of the LISTENER
------------------------
Alias LISTENER
Version TNSLSNR for Linux: Version 19.0.0.0.0 - Production
Start Date 24-MAR-2022 01:23:34
Uptime 0 days 3 hr. 35 min. 3 sec
Trace Level off
Security ON: Local OS Authentication
SNMP OFF
Listener Parameter File /u01/app/19.0.0.0/grid/network/admin/listener.ora
Listener Log File /u01/app/grid/diag/tnslsnr/tgt/listener/alert/log.xml
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=LISTENER)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.100.118)(PORT=1521)))
Services Summary...
Service "+APX" has 1 instance(s).
Instance "+APX1", status READY, has 1 handler(s) for this service...
Service "+ASM" has 1 instance(s).
Instance "+ASM1", status READY, has 1 handler(s) for this service...
Service "+ASM_DATA" has 1 instance(s).
Instance "+ASM1", status READY, has 1 handler(s) for this service...
Service "+ASM_RECO" has 1 instance(s).
Instance "+ASM1", status READY, has 1 handler(s) for this service...
Service "DB19XDB.publicsn.dblabvcn.oraclevcn.com" has 1 instance(s).
Instance "DB19", status READY, has 1 handler(s) for this service...
Service "DB19_iad27v.publicsn.dblabvcn.oraclevcn.com" has 2 instance(s).
Instance "DB19", status UNKNOWN, has 1 handler(s) for this service...
Instance "DB19", status READY, has 2 handler(s) for this service...
Service "da5a491beb141ae2e0537664a8c04357.publicsn.dblabvcn.oraclevcn.com" has 1
instance(s).
Instance "DB19", status READY, has 2 handler(s) for this service...
Service "db19_pdb1.publicsn.dblabvcn.oraclevcn.com" has 1 instance(s).
Instance "DB19", status READY, has 2 handler(s) for this service...
The command completed successfully
[grid@tgt admin]$

Changing parameters in standby database


alter system set fal_server ='DB19_iad2zj' scope=both;
alter system set standby_file_management='AUTO' ;

alter system set log_archive_config='dg_config=(DB19_iad2zj,DB19_iad27v)' ;


ALTER SYSTEM SET log_archive_dest_1='location=use_db_recovery_file_dest
valid_for=(all_logfiles,all_roles) db_unique_name=DB19_iad27v' SCOPE=both;

alter system set log_archive_dest_2='SERVICE= DB19_SRC ASYNC


VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=DB19_iad2zj' ;

Create directory Structure in Standby database


start the standby database using pfile

# script duplicate_c.sh
date +"Duplicate iniciado em %d/%m/%Y as %H:%M:%S"

rman msglog duplicate_db19.log <<EOF


connect target sys/WelC0me_123#@DB19_SRC
connect auxiliary sys/WelC0me_123#@DB19_TG
run {
allocate auxiliary channel aux1 device type disk;
allocate auxiliary channel aux2 device type disk;
allocate channel disk1 device type disk;
allocate channel disk2 device type disk;
duplicate target database for standby from active database nofilenamecheck;
switch datafile all;
release channel aux1;
release channel aux2;
}
EOF

date +"Duplicate finalizado em %d/%m/%Y as %H:%M:%S"

################
[oracle@tgt ~]$ chmod +x duplicate_c.sh

nohup ./duplicate_c.sh >/dev/null &

connect to the standby database


set lines 500
set pages 500
set time on
set timing on
column HOST_NAME format a35
select DISTINCT instance_name, name "DB_NAME", created, host_name, open_mode, status,
log_mode, database_role, LOGINS, to_char(startup_time,'DD-MON-YYYY HH:MI:SS')
"STARTUP_TIME" from gv$database, gv$instance order by instance_name;

Now start the redo apply process on the standby database.


SQL> alter database recover managed standby database disconnect from session;

Check on the standby database that it is applying archivers with this.

SQL> select role, thread#, sequence#, action from v$dataguard_process;

ROLE THREAD# SEQUENCE# ACTION


------------------------ ---------- ---------- ------------
recovery apply slave 0 0 IDLE
managed recovery 0 0 IDLE
gap manager 0 0 IDLE
redo transport timer 0 0 IDLE
recovery apply slave 0 0 IDLE
recovery apply slave 0 0 IDLE
archive local 0 0 IDLE
archive redo 0 0 IDLE
archive redo 0 0 IDLE
recovery apply slave 0 0 IDLE
archive redo 0 0 IDLE

ROLE THREAD# SEQUENCE# ACTION


------------------------ ---------- ---------- ------------
redo transport monitor 0 0 IDLE
log writer 0 0 IDLE
recovery logmerger 1 5 WAIT_FOR_LOG

Now go to the primary and check the archivers too and do a switch logfile to generate a new
archiver

SQL> select sequence#, first_time, next_time from v$archived_log order by sequence#;

SEQUENCE# FIRST_TIM NEXT_TIME


---------- --------- ---------
1 16-MAR-22 16-MAR-22
2 16-MAR-22 19-MAR-22
3 19-MAR-22 22-MAR-22
4 22-MAR-22 24-MAR-22
5 24-MAR-22 24-MAR-22

SQL> alter system switch logfile;

System altered.

SQL> /

System altered.

SQL> /

System altered.

SQL>

Now go to the standby database and check that the new archiver has been applied.

[oraprd@dr01dbadm01 ~]$ cat mrp_check.sh


#!/bin/bash
sqlplus -s / as sysdba <<EOF
SET LINES 500 PAGES 150
SET UNDERLINE =
col HOST_NAME for a50
SELECT NAME as DB_NAME,INSTANCE_NAME,
HOST_NAME,TO_CHAR(STARTUP_TIME,'DD-MON-YYYY HH24:MI:SS') "STARTUP",
DATABASE_ROLE, OPEN_MODE, status from GV\$INSTANCE, V\$DATABASE
order by 2;
SET UNDERLINE =
col inst_id heading 'Inst' for 99
col process for a10
col thread# for 99
col sequence# for 99999999
col block# for 99999999999999
select inst_id, process, status MRP_stat, thread#, sequence#, block#
from gv\$managed_standby
where process like 'MRP%' or process like 'RFS%' and status != 'IDLE'
order by inst_id,process,thread# ;
col "Thread" for 99
column dummy noprint;
compute sum of Difference on dummy;
break on dummy;
SELECT null dummy, al.thrd "Thread", almax "Last Seq Received", lhmax
"Last Seq Applied",  almax-lhmax "Difference"
FROM
 (SELECT thread# thrd, MAX(sequence#) almax FROM v\$archived_log WHERE
resetlogs_change#=(SELECT resetlogs_change# FROM v\$database) GROUP BY
thread#) al,
 (SELECT thread# thrd, MAX(sequence#) lhmax FROM v\$log_history  WHERE
resetlogs_change#=(SELECT resetlogs_change# FROM v\$database) GROUP BY
thread#) lh
 WHERE al.thrd = lh.thrd
 ORDER BY 1;
select 'Lag ' || ROUND((sysdate - r.timestamp)*24*60*60) || ' Secs' as
"Lag Secs", 'Lag ' || ROUND((sysdate - r.timestamp)*24) || ' Hours' as
"Lag hours"
from gv\$recovery_progress r
where r.start_time = (select max(start_time) from gv\
$recovery_progress)
and r.item = 'Last Applied Redo';
@recovery_progress.sql
exit
EOF

[oraprd@dr01dbadm01 ~]$ cat recovery_progress.sql


COLUMN inst_id             HEADING "I#"                           
FORMAT 99
COLUMN start_time          HEADING "Start Time"                   
FORMAT a18
COLUMN type                HEADING "Type"                         
FORMAT a20
COLUMN item                HEADING "Item"                         
FORMAT a25
COLUMN units               HEADING "Units"                        
FORMAT a10
COLUMN sofar               HEADING "SoFar"                        
FORMAT a45
COLUMN total               HEADING "Total"                        
FORMAT 999,999,999,999
COLUMN timestamp           HEADING "Start Time"                   
FORMAT a18
COLUMN comments            HEADING "Comments"                     
FORMAT a18
SELECT r.inst_id
     --, TO_CHAR(r.start_time,'DD-MON-YY HH24:MI:SS') start_time
     --, r.type
     , r.item
     , CASE r.item
           WHEN 'Last Applied Redo' THEN TO_CHAR(r.timestamp,'DD-MON-
YY HH24:MI:SS') || ' , ' || r.comments
                                       || chr(10) || 'ApplyLag ' || 
REPLACE(REPLACE(TO_CHAR( CAST(sysdate as TIMESTAMP) -
CAST( r.timestamp as TIMESTAMP))
                                                                       
         ,'+0000000','+')
                                                              ,'.00000
0','')
         WHEN 'Active Time'       THEN FLOOR(r.sofar/3600) || 'h ' ||
FLOOR(MOD(r.sofar,3600)/60) || 'm ' ||  MOD(r.sofar,60) || 's'
         WHEN 'Elapsed Time'      THEN FLOOR(r.sofar/3600) || 'h ' ||
FLOOR(MOD(r.sofar,3600)/60) || 'm ' ||  MOD(r.sofar,60) || 's'
                                       || chr(10) || 'StartTime: ' ||
TO_CHAR(r.start_time,'DD-MON-YY HH24:MI:SS')
         ELSE TRIM(TO_CHAR(r.sofar,'999,999,999,999')) || ' ' ||
r.units
      END  SoFar
     --, r.total
  FROM gv$recovery_progress r
 WHERE r.start_time = (SELECT MAX(start_time) from
gv$recovery_progress)
 ORDER BY DECODE(r.item
                 ,'Last Applied Redo',1
                 ,'Standby Apply Lag',2
                 ,'Active Apply Rate',3
                 ,'Average Apply Rate',4
                 ,'Maximum Apply Rate',5
                 ,'Redo Applied',6
                 ,'Log Files',7
                 ,'Apply Time per Log',8
                 ,'Checkpoint Time per Log',9
                 ,'Active Time',21
                 ,'Elapsed Time',22
             ,999
                 )
;
Perform a switchover with sqlplus

Fist confirm that the synchronization is ready to perform a switchover on primary

alter database switchover to DB19_iad27v verify

[oracle@src trace]$ tail -100f alert_DB19.log

2022-03-24T16:59:45.203007+00:00
alter database switchover to DB19_iad27v verify
2022-03-24T16:59:48.709487+00:00
SWITCHOVER VERIFY: Send VERIFY request to switchover target
DB19_IAD27V
2022-03-24T16:59:51.285605+00:00
SWITCHOVER VERIFY COMPLETE: READY FOR SWITCHOVER
Completed: alter database switchover to DB19_iad27v verify

If you don’t get any error in the previous command then all is good.

If you do get errors, then check the alert file for more details.

On the primary database check that there are no gaps

SQL> select status, gap_status from v$archive_dest_status where dest_id = 2;

STATUS GAP_STATUS
--------- ------------------------
VALID NO GAP

SQL>

Switchover to standby database


Execute from the primary database:
SQL> alter database switchover to DB19_iad27v ;

Now go to srv2 (which is now the primary database) and open the database

[oracle@tgt ~]$ sqlplus / as sysdba

SQL*Plus: Release 19.0.0.0.0 - Production on Thu Mar 24 17:07:12 2022


Version 19.14.0.0.0

Copyright (c) 1982, 2021, Oracle. All rights reserved.


Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.14.0.0.0

SQL> alter database open ;

Database altered.

SQL>

Now go to srv1 (the new standby database) and mount the database

SQL> startup mount


SQL> alter database recover managed standby database disconnect;
Database altered.
SQL>

SQL> select database_role from v$database;

DATABASE_ROLE
----------------
PHYSICAL STANDBY

SQL> select role, thread#, sequence#, action from v$dataguard_process;

ROLE THREAD# SEQUENCE# ACTION


------------------------ ---------- ---------- ------------
recovery apply slave 0 0 IDLE
recovery apply slave 0 0 IDLE
recovery apply slave 0 0 IDLE
recovery apply slave 0 0 IDLE
recovery logmerger 1 46 APPLYING_LOG
managed recovery 0 0 IDLE
RFS archive 0 0 IDLE
RFS async 1 46 RECEIVING
archive redo 0 0 IDLE
archive redo 0 0 IDLE
redo transport timer 0 0 IDLE

ROLE THREAD# SEQUENCE# ACTION


------------------------ ---------- ---------- ------------
gap manager 0 0 IDLE
archive local 0 0 IDLE
archive redo 0 0 IDLE
redo transport monitor 0 0 IDLE
log writer 0 0 IDLE
archive redo 1 44 CLOSING
RFS ping 1 46 IDLE

18 rows selected.

SQL>

perform a switchback
on primary(tgt)

alter database switchover to DB19_iad2zj verify ;

SQL> alter database switchover to DB19_iad2zj verify ;

Database altered.

SQL> alter database switchover to DB19_iad2zj ;

Database altered.

SQL>

On newly switched primary(src)

SQL> show parameter uniq

NAME TYPE VALUE


------------------------------------ -----------
------------------------------
db_unique_name string DB19_iad2zj
SQL> alter database open;

Database altered.

SQL>

On tgt mount the database and start the recovery process again

SQL> startup mount


ORACLE instance started.

Total System Global Area 1.4496E+10 bytes


Fixed Size 9151688 bytes
Variable Size 2013265920 bytes
Database Buffers 1.2449E+10 bytes
Redo Buffers 24399872 bytes
Database mounted.
SQL> alter database recover managed standby database disconnect;

Database altered.

SQL>

If you run into problems, check the parameters on the primary and the standby
database with this query.

set linesize 200 pages 50


col value for a85
col name for a50

select name, value


from gv$parameter
where name in ('db_name','db_unique_name','log_archive_config',
'log_archive_dest_1','log_archive_dest_2','log_archive_dest_3',
'log_archive_dest_state_1','log_archive_dest_state_2','log_archive_des
t_state_3',
'remote_login_passwordfile','log_archive_format','log_archive_max_proc
esses',
'fal_server','fal_client','db_file_name_convert',
'log_file_name_convert', 'standby_file_management')
order by 1;
Step by Step Data Guard Broker Configuration in Oracle 19c
The Oracle Data Guard broker is a distributed management framework that automates and
centralizes the creation, maintenance, and monitoring of Data Guard configurations.

DB19_iad2zj is the primary database and DB19_iad27v is the standby database.

1. Reset LOG_ARCHIVE_DEST_2
First you need to clear the value for LOG_ARCHIVE_DEST_2 on the primary and on the
standby database.

SQL> !hostname
src

SQL> alter system set LOG_ARCHIVE_DEST_2='' SCOPE=BOTH sid='*';

System altered.

SQL>

SQL> !hostname
tgt

SQL> alter system set LOG_ARCHIVE_DEST_2='' SCOPE=BOTH sid='*';

System altered.

SQL>

Set dg_broker_config_file

Set the parameter dg_broker_config_file1 and dg_broker_config_file2 on all instances


of primary and standby.

The default location of the broker configuration file is $ORACLE_HOME/dbs or


$ORACLE_HOME/database.

If you don’t have a RAC database no need to use the sid=’*’.

ALTER SYSTEM SET dg_broker_config_file1 = '<path/file_name>.dat'


scope=both sid='*';
ALTER SYSTEM SET dg_broker_config_file2 = '<path/file_name>.dat'
scope=both sid='*';
OR in case of ASM file system use:

ALTER SYSTEM SET dg_broker_config_file1 = '<+disk


group/file_name>.dat' scope=both sid='*';
ALTER SYSTEM SET dg_broker_config_file2 = '<+disk
group/file_name>.dat' scope=both sid='*';

On Primary

SQL> ALTER SYSTEM SET dg_broker_config_file1 =


'+DATA/DB19_IAD2ZJ/DATAFILE/dr1prime.dat' scope=both ;

System altered.

SQL> ALTER SYSTEM SET dg_broker_config_file2 =


'+DATA/DB19_IAD2ZJ/DATAFILE/dr2prime.dat' scope=both ;

System altered.

SQL>

On standby

SQL> show parameter uniq

NAME TYPE VALUE


------------------------------------ -----------
------------------------------
db_unique_name string DB19_iad27v
SQL> ALTER SYSTEM SET dg_broker_config_file1 =
'+DATA/DB19_IAD27V/DATAFILE/dr1prime.dat' scope=both ;

System altered.

SQL> ALTER SYSTEM SET dg_broker_config_file2 =


'+DATA/DB19_IAD27V/DATAFILE/dr2prime.dat' scope=both ;

System altered.

SQL>

Enable the broker

Enable the broker on both primary and standby databases.

If you don’t have a RAC database, no need to use sid=’*’.


ALTER SYSTEM SET DG_BROKER_START=TRUE scope=both ;

Create the configuration


Connect to DGMGRL on primary:
[oracle@src ~]$ dgmgrl
DGMGRL for Linux: Release 19.0.0.0.0 - Production on Thu Mar 24
18:02:41 2022
Version 19.14.0.0.0

Copyright (c) 1982, 2019, Oracle and/or its affiliates. All rights
reserved.

Welcome to DGMGRL, type "help" for information.


DGMGRL>
DGMGRL> CONNECT sys/WelC0me_123#;
Connected to "DB19_iad2zj"
Connected as SYSDBA.
DGMGRL>

DGMGRL> CREATE CONFIGURATION 'MYCONF' AS PRIMARY DATABASE IS


'DB19_iad2zj' CONNECT IDENTIFIER IS DB19_SRC;
Configuration "MYCONF" created with primary database "DB19_iad2zj"
DGMGRL>

Add the standby to the configuration:

DGMGRL> ADD DATABASE 'DB19_iad27v' AS CONNECT IDENTIFIER IS DB19_TG


MAINTAINED AS PHYSICAL;
Database "DB19_iad27v" added
DGMGRL>

Configure the listeners


Configure the listener on the primary server.

SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC = (GLOBAL_DBNAME = DB19_iad2zj.publicsn.dblabvcn.oraclevcn.com)
(ORACLE_HOME = /u01/app/oracle/product/19.0.0.0/dbhome_1)
(SID_NAME = DB19)
)

(SID_DESC =
(GLOBAL_DBNAME=DB19_iad2zj_dgmgrl)
(ORACLE_HOME=/u01/app/oracle/product/19.0.0.0/dbhome_1)
(SID_NAME=DB19)
)
)

Configure the listener on the standby server.

SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC = (GLOBAL_DBNAME =
DB19_iad27v.publicsn.dblabvcn.oraclevcn.com)
(ORACLE_HOME =
/u01/app/oracle/product/19.0.0.0/dbhome_1)
(SID_NAME = DB19)
)

(SID_DESC =
(GLOBAL_DBNAME=DB19_iad27v_dgmgrl)

(ORACLE_HOME=/u01/app/oracle/product/19.0.0.0/dbhome_1)
(SID_NAME=DB19)
)

Enable the configuration

You might also like