Monday, September 6, 2010

Creating a physical standby database

Requirement

Create a standby database for the primary production database.


Pre-requisites

1. The primary database is in archive log mode.


2. Primary and standby database names:

Primary DB Name: PRIM
Primary DB Host: primary.hostname.com


Standby DB Name: STBY
Standby DB Host: standby.hostname.com


3. Initialization parameters required for enabling standby instance to be set on the primary:





*.LOG_ARCHIVE_CONFIG='DG_CONFIG=(PRIM,STBY)'

*.LOG_ARCHIVE_DEST_2='SERVICE=STBY LGWR ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=STBY'

*.log_archive_dest_state_2='ENABLE'

*.log_file_name_convert='/u001/app/oracle/stby/data/','/opt/apps/prim/data/'

*.standby_file_management='auto'

*.db_file_name_convert='/u001/app/oracle/stby/data/','/opt/apps/prim/data/'

*.fal_client='PRIM'

*.fal_server='STBY'

*.db_name='PRIM'

*.db_unique_name='PRIM'





4. The listener and tnsnames to be modified on the primary:

listener.ora on primary



# When primary becomes standby (switchover).
STBY =
(ADDRESS_LIST =
(ADDRESS= (PROTOCOL= IPC)(KEY= EXTPROCSTBY))
(ADDRESS= (PROTOCOL= TCP)(Host= primary.hostname.com )(Port= 1532))
)

SID_LIST_STBY =
(SID_LIST =
(SID_DESC =
(ORACLE_HOME= /opt/dbms/app/oracle/product/oraprim/10.2.0)
(SID_NAME = STBY)
)
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = /opt/dbms/app/oracle/product/oraprim/10.2.0)
(PROGRAM = extproc)
)
)

# Normal primary database listener
PRIM =
(ADDRESS_LIST =
(ADDRESS= (PROTOCOL= IPC)(KEY= EXTPROCPRIM))
(ADDRESS= (PROTOCOL= TCP)(Host= primary.hostname.com )(Port= 1532))
)

SID_LIST_PRIM =
(SID_LIST =
(SID_DESC =
(ORACLE_HOME= /opt/dbms/app/oracle/product/oraprim/10.2.0)
(SID_NAME = PRIM)
)
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = /opt/dbms/app/oracle/product/oraprim/10.2.0)
(PROGRAM = extproc)
)
)



tnsnames.ora on primary




STBY=
(DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=standby.hostname.com)(PORT=1526))
(CONNECT_DATA=
(SID=STBY)
)
)

PRIM = (DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=primary.hostname.com)(PORT=1532))
(CONNECT_DATA=(SID=PRIM))
)




Backup tnsnames.ora on primary (for switchover)



## Create a tnsnames_ifile.ora.
STBY=
(DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=primary.hostname.com)(PORT=1532))
(CONNECT_DATA=
(SID=STBY)
)
)

PRIM = (DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=standby.hostname.com)(PORT=1526))
(CONNECT_DATA=(SID=PRIM))
)





5. Create the initialization file for the standby database.



*.db_create_file_dest='/u001/app/oracle/stby/data'

*.db_file_name_convert='/opt/apps/prim/data/','/u001/app/oracle/stby/data/'

*.db_name='PRIM'

*.db_recovery_file_dest='/u001/app/oracle/stby/flashrecovery'

*.db_recovery_file_dest_size=42949672960

*.db_unique_name='STBY'

*.fal_client='STBY'

*.fal_server='PRIM'

*.LOG_ARCHIVE_CONFIG='DG_CONFIG=(PRIM,STBY)'

*.LOG_ARCHIVE_DEST_1='LOCATION=/u001/app/oracle/stby/arch/
VALID_FOR=(ALL_LOGFILES,ALL_ROLES)
DB_UNIQUE_NAME=STBY'

*.LOG_ARCHIVE_DEST_2='SERVICE=PRIM LGWR ASYNC
VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE)
DB_UNIQUE_NAME=PRIM'

*.LOG_ARCHIVE_DEST_STATE_1='ENABLE'

*.LOG_ARCHIVE_DEST_STATE_2='ENABLE'

*.log_file_name_convert='/opt/apps/prim/data/','/u001/app/oracle/stby/data/'

*.standby_file_management='auto'



6. Create the listener.ora and the tnsnames.ora files:

listener.ora on standby



# For normal standby operations
STBY =
(ADDRESS_LIST =
(ADDRESS= (PROTOCOL= IPC)(KEY= EXTPROCSTBY))
(ADDRESS= (PROTOCOL= TCP)(Host= standby.hostname.com )(Port= 1526))
)

SID_LIST_STBY =
(SID_LIST =
(SID_DESC =
(ORACLE_HOME= /u001/app/oracle/stby/10203)
(SID_NAME = STBY)
)
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = /u001/app/oracle/stby/10203)
(PROGRAM = extproc)
)
)

# For switchover (ie., when standby becomes the primary).
PRIM =
(ADDRESS_LIST =
(ADDRESS= (PROTOCOL= IPC)(KEY= EXTPROCPRIM))
(ADDRESS= (PROTOCOL= TCP)(Host= standby.hostname.com )(Port= 1526))
)

SID_LIST_PRIM =
(SID_LIST =
(SID_DESC =
(ORACLE_HOME= /u001/app/oracle/stby/10203)
(SID_NAME = PRIM)
)
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = /u001/app/oracle/stby/10203)
(PROGRAM = extproc)
)
)



tnsnames.ora for standby




STBY=
(DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=SUOMT34L.dev.qintra.com)(PORT=1526))
(CONNECT_DATA=
(SID=STBY)
)
)

PRIM=
(DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=primary.hostname.com)(PORT=1532))
(CONNECT_DATA=
(SID=PRIM)
)
)




Backup tnsnames.ora on standby (for switchover)



## Create a tnsnames_ifile.ora.
STBY=
(DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=primary.hostname.com)(PORT=1532))
(CONNECT_DATA=
(SID=STBY)
)
)

PRIM = (DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=standby.hostname.com)(PORT=1526))
(CONNECT_DATA=(SID=PRIM))
)




7. Last but not the least, SSH Equivalence needs to be established between the primary database owner and the standby database owner, to facilitate the transfer of archives.



Steps - using manual hotbackup

1. Generate the hot backup script on the primary database using the below sql:


set echo off heading off feedback off verify off
set pagesize 0
spool backup.sql
set linesize 80
set serveroutput on size 1000000
set linesize 150
DECLARE
cursor C_ts_name is
select tablespace_name from dba_tablespaces
order by tablespace_name;
BEGIN
for ts_name in C_ts_name loop
dbms_output.put_line('alter tablespace ' ts_name.tablespace_name
' begin backup;');
for dbf_name in (select file_name from sys.dba_data_files
where tablespace_name = ts_name.tablespace_name) loop
dbms_output.put_line(' scp -p ' dbf_name.file_name
' standby_db_owner@standby.hostname.com:/u001/app/oracle/stby/data/.');
end loop;
dbms_output.put_line('alter tablespace ' ts_name.tablespace_name
' end backup;');
end loop;
END;
/






2. Kick off the hotbackup using the script so generated, on the primary database. This script also takes care of the copying of datafiles to the standby server.


3. Once the backup is completed, copy all the archives generated during the backup from primary archive location to the standby archive location.


4. Generate the standby controlfile on the primary using the below command:




Alter database create standby controlfile as '<destination>';

Eg:

SQL> alter database create standby controlfile as '/export/home/oraprim/sb_cntrl01.dbf';






The created file must meet two conditions:

a. Its filename must be different from any other control file.

b. Must be created after the backup of the datafiles.


5. Copy the controlfile so generated from the primary to the standby. To be on the safer side, always multiplex the standby control files. So, copy the standby controlfiles as per the multiplexed order. Also ensure that the parameter control_files in the init.ora is also in sync with this.

6. Start the standby listener.

7. Mount the standby database.

SQL> startup nomount

SQL> alter database mount standby database;

8. Recover the standby database till the latest archive log using the below command. Note that the command "alter database recover continue default" needs to be executed as many times as there are archive logs to be applied!

Now, I prefer to do an incomplete recovery till the lastest SCN. Find the scn number, using the below steps and then perform the recovery.

a. Find the latest archive log generated on the primary after the backup is done.

b. Find the next_change# from v$archived_log view:

SQL> select next_change# from v$archived_log where sequence# = &sequence#;

SQL> alter database recover standby database until change <SCN>;

SQL> alter database recover continue default;


9. After all the archives have been applied, cancel the recovery. Note that you should not receive any errors (esp. ORA-1547 errors) when you cancel the recovery.



SQL> alter database recover cancel;




10. Open the database for read only access. The temp files will be added automatically.


SQL> alter database open read only;



11. Shutdown the database and then mount the standby database.


SQL> shutdown immediate

SQL> startup nomount

SQL> alter database mount standby database;



12. Start the MRP (managed recovery process):


SQL> alter database recover managed standby database disconnect;




13. Perform log switches on the primary to test the MRP. The archives on the primary should automatically be copied over to the standby archive location and automatically be applied.



Voila! Your dataguard is ready to be used.

No comments: