10 Nisan 2011 Pazar

Step by Step creating a Physical Standby Database on 11gR2


10gR2 için dataguard kurulumundan bahsetmiştik, şimdi aynı işlemleri 11gR2 için yapıp bir sonraki adımda da dgmgrl ile switcover failover işlemlerinden bahsetmeyi planlıyorum.  İlk yazımda bahsetmiş olduğum bazı tanım ve ön gereksinimler kısmına artık burada değinmiyorum.  10gR2 için dataguard kurulumundan bahsederken manuel kurulum yapmıştık. Dbf’ leri biz taşımıştık, initfile’ deki parametreleri biz edit ederek üzerinde değişiklikler yapmıştık. 11gR2 için dataguard kurulumunda bu adımların hiçbirini yapmayacağız. Rman’ i kullanarak tüm işi oracle’ a bırakarak nasıl yapacağımız üzerinde konuşacağız.
Kurulumuna başlamadan önce elimizdekilere bir bakalım.  2 tane işletim sistemi linux 5.5 olan sunucumuz, sunucuların birinde oracle 11gR2 database kurulu diğerinde ise sadece software kurulu durumda. Primary sunucumuzun SID=dg1, dataguard olacak olan database’ imizin SID’si dg2. 

Bu özet bilgilerden sonra physical standby database’ imizi create etmeye başlayabiliriz ;

·         Primary database’ imizi force logging moda alıyoruz;

Alter database force logging

·         Primary database’ in archive modda olması gerekiyor.
Aşağıdaki script ile kontrol edebilirsiniz. Sonuç NOARCHIVELOG dönerse aşağıdaki adımları takip ederek archive moda alabilirsiniz.

select log_mode from v$database  ;

SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
ALTER DATABASE ARCHIVELOG;
ALTER DATABASE OPEN;

--  archive ile ilgili iki önemli parametreyi set ediyoruz.

ALTER SYSTEM SET log_archive_format='arch_%t_%s_%r_.arc' SCOPE=spfile

ALTER SYSTEM SET log_archive_dest_1='location=D:\arch' SCOPE=spfile

·         Primary database’ inde yok ise bir password file create edilir;
orapwd file=PWDist.ora password=oracle entries=5 force=Y

·         Primary Database’ ine Standby Redo logların create ve configure edilmesi ;
Burada önerilen, primary database’ deki redo logların size’ ı ile standby için create edilecek redo log’ ların size’ larının aynı olmasıdır.  Kaç tane oluşturulacağını şu şekilde hesaplayabiliriz ;
Create Edilecek Standby Redo Log Sayısı = (maximum number of logfiles for each thread + 1) * maximum number of threads
Bir örnekle açıklayalım ;

Primary database’ indeki redo loglarımız,

SQL> select group#,THREAD#,BYTES,status from v$log;

    GROUP#    THREAD#      BYTES STATUS
---------- ---------- ---------- ----------------
         1          1   52428800 INACTIVE
         2          1   52428800 INACTIVE
         3          1   52428800 CURRENT

thread başına düşen log sayısı = 3
maximum number of thread = 1
Dolayısıyla create edilecek log sayısı = (3+1)*1 = 4

Bu örnek benim primary database’ im deki ile aynı dolayısıyla bende 4 tane standby redo logları create ediyorum.

ALTER DATABASE ADD STANDBY LOGFILE GROUP 4 ('c:\oracle10g\standby_redo\standby_redo04.log') SIZE 50M
Database altered

ALTER DATABASE ADD STANDBY LOGFILE GROUP 5 ('c:\oracle10g\standby_redo\standby_redo05.log') SIZE 50M
Database altered

ALTER DATABASE ADD STANDBY LOGFILE GROUP 6 ('c:\oracle10g\standby_redo\standby_redo06.log') SIZE 50M
Database altered

ALTER DATABASE ADD STANDBY LOGFILE GROUP 7 ('c:\oracle10g\standby_redo\standby_redo07.log') SIZE 50M
Database altered

Buradaki Group noları önemli, sıra ile devam etmesi gerekiyor, aralarda atlamalar olmayacak şekilde create ediyoruz.

Primary database’ ine standby redolog ları neden oluşturuyoruz sorusuna, dataguard kurulumunda aslında buna gerek yok ama kurulumdan sonra herhangi bir zamanda
gereklidir. 

Standby redologlar create edildikden sonra aşağıdaki sorgu ile kontrol edebiliriz ;

SELECT GROUP#,THREAD#,SEQUENCE#,ARCHIVED,STATUS FROM V$STANDBY_LOG

GROUP#    THREAD#        SEQUENCE#    ARCHIVED       STATUS   
------          -------               ---------                        --------              ----------
     4           0                      0                      YES                  UNASSIGNED
     5           0                      0                      YES                  UNASSIGNED
     6           0                      0                      YES                  UNASSIGNED
     7           0                      0                      YES                  UNASSIGNED
4 rows selected

·         Primary database’ in initial parametrelerinin düzenlenmesi  ;

Redo logların transferi için primary database üzerinde bazı initial parametrelerinin düzenlenmesi gerekmektedir. Bunun yanısıra yine olası bir switchover durumunda hata alınmaması için (standby gibi davranabilmesi için)  bazı eklemelerinde yapılması faydalı olacaktır.
Bilmemiz gerekenler şunlar;
Primary database’ imin                           db_unique_name = dg1
                                                     Net_service_name = dg1
Standby database’ imin               db_unique_name = dg2
                                                     Net_service_name = dg2

Pfile’ de yapılacak olan değişiklerin bir kısmı zaten şu anki pfile’ inizde olan parametreler, kontrol etmeniz yeterli olacaktır.

DB_NAME, CONTROL_FILES, REMOTE_LOGIN_PASSWORDFILE  (exclusive olması gerekiyor), LOG_ARCHIVE_FORMAT (db archive modda olduğunda bu parametrede pfile’ inizde olacaktır.)

Aşağıdaki parametreleri ekliyoruz.

*.control_files='/data/oracle/oradata/dg1/control01.ctl','/data/oracle/flash_recovery_area/dg1/control02.ctl'
*.db_name='dg1'
*.DB_UNIQUE_NAME=dg1
*.log_archive_dest_1='location=/data/oracle/arch'
*.log_archive_dest_state_1='ENABLE'
*.log_archive_dest_state_2='ENABLE'
*.log_archive_format='arch_%t_%s_%r_.arc'
*.remote_login_passwordfile='EXCLUSIVE'
*.LOG_ARCHIVE_CONFIG='DG_CONFIG=(dg1,dg2)'
*.LOG_ARCHIVE_DEST_1='LOCATION=/data/oracle/arch/ VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=dg1'
*.LOG_ARCHIVE_DEST_2='SERVICE=dg2 ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=dg2'
*.LOG_ARCHIVE_DEST_STATE_1=ENABLE
*.LOG_ARCHIVE_DEST_STATE_2=ENABLE
*.LOG_ARCHIVE_MAX_PROCESSES=30
*.FAL_SERVER=dg2
*.DB_FILE_NAME_CONVERT='dg2','dg1'
*.LOG_FILE_NAME_CONVERT='/data/oracle/arch_dis/','/data/oracle/arch','/data/oracle/arch_dis/','/data/oracle/arch'
*.STANDBY_FILE_MANAGEMENT=AUTO STANDBY_FILE_MANAGEMENT=AUTO

Log_archive_process’ si 30 olarak set ettim ben, oracle’ ın standby için önermiş olduğu process sayısı 30’ dır. Daha azda yapabilirsiniz.

·         Hem primary sunucuda hemde standby tarafındaki listener ve tnsnames.ora dosyalarında aşağıdaki eklemeleri yapıp, listener servisini stop – start ediyoruz.

Tnsnames.ora doyasında her iki instance’ a ait bilgiler yer alacak şekilde düzenliyoruz.
DG2 =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 10.1.3.145)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = dg2)
    )
  )

DG1 =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 10.1.3.144)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = dg1)
    )
  )

Listener.ora dosyasınıda aşağıdaki satırları ekliyoruz.
SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (SID_NAME = dg1)
      (GLOBAL_DBNAME = dg1)
      (ORACLE_HOME = /data/oracle/11.2.0/dbhome_1)
    )
    (SID_DESC =
      (SID_NAME = dg2)
      (GLOBAL_DBNAME = dg2)
      (ORACLE_HOME = /data/oracle/11.2.0/dbhome_1)
    )
  )

·         Standby tarafına profile dosyası üzerinde oracle_home, sid gibi değişiklikleri yaptıkdan sonra, orapwd dosyasını primary db’ olduğu sunucudan buraya kopyalıyoruz. Burada orapwdg1 ve orapwdg2 olacak şekilde iki tane passord file oluşturuyoruz. (orapwdg1 dosyası, switchover durumunda problem olmaması için) 

·         Standby sunucuda $ORACLE_HOME/dbs klasörü altına manuel olarak (vi editörü ile) initdg2.ora dosyası create edip içerisine sadece DB_NAME=DG2 parametresini ekleyip kaydediyoruz.

·         Standby tarafında $ORACLE_BASE altına /admin/SID/admin klasörünü create ediyoruz.
(rman komutunu çalıştırdığınızda eksik create edilmiş olan bir lokasyon var ise hata verecektir, böyle bir durumda standbydaki oradata lokasyonu silip primary tarafında rman’ e tekrar connect olup komutu tekrar başlatabilirsiniz.)

·         Yine standby tarafında $ORACLE_BASE altına /oradata/SID klasörünü create ediyoruz.

·         Standby database’ ini nomount moda alıyoruz.

[oracle@betadataguard2 admin]$ sqlplus "/as sysdba"
SQL*Plus: Release 11.2.0.1.0 Production on Sun Apr 17 00:26:05 2011
Copyright (c) 1982, 2009, Oracle.  All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
SQL> startup nomount pfile=$ORACLE_HOME/dbs/initdg2.ora;
ORACLE instance started.

Total System Global Area  217157632 bytes
Fixed Size                  2211928 bytes
Variable Size             159387560 bytes
Database Buffers           50331648 bytes
Redo Buffers                5226496 bytes
SQL>

·         Primary sunucusu üzerinden Rman’ e connect olup komutumuzu çalıştırıyoruz.

[oracle@betadataguard1 standby_kurulum]$ rman

Recovery Manager: Release 11.2.0.1.0 - Production on Sat Apr 16 19:45:51 2011

Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.
RMAN> connect target sys

target database Password:
connected to target database: DG1 (DBID=1729884635)

RMAN> connect auxiliary sys@dg2

auxiliary database Password:
connected to auxiliary database: DG2 (not mounted)

Çalıştıracağımız komutumuz ;

run {
         allocate channel prmy1 type disk;
      allocate channel prmy2 type disk;
      allocate channel prmy3 type disk;
      allocate channel prmy4 type disk;
      allocate auxiliary channel stby type disk;
      duplicate target database for standby from active database
      spfile
              parameter_value_convert 'dg1','dg2'
             set db_unique_name='dg2'
             set db_file_name_convert='/dg1/','/dg2/'
             set log_file_name_convert='/dg1/','/dg2/'
             set control_files='/data/oracle/oradata/dg2/dg2.ctl'
             set log_archive_max_processes='5'
             set fal_client='dg2'
             set fal_server='dg1'
             set standby_file_management='AUTO'
             set log_archive_config='dg_config=(dg1,dg2)'
             set log_archive_dest_2='service=dg1 ASYNC valid_for=(ONLINE_LOGFILE,PRIMARY_ROLE) db_unique_name=dg1'
      ;
      }

Scriptin outputu ;

RMAN> run {
2>      allocate channel prmy1 type disk;
3>      allocate channel prmy2 type disk;
4>      allocate channel prmy3 type disk;
5>      allocate channel prmy4 type disk;
6>      allocate auxiliary channel stby type disk;
7>      duplicate target database for standby from active database
8>      spfile
9>              parameter_value_convert 'dg1','dg2'
10>             set db_unique_name='dg2'
11>             set db_file_name_convert='/dg1/','/dg2/'
12>             set log_file_name_convert='/dg1/','/dg2/'
13>             set control_files='/data/oracle/oradata/dg2/dg2.ctl'
14>             set log_archive_max_processes='5'
15>             set fal_client='dg2'
16>             set fal_server='dg1'
17>             set standby_file_management='AUTO'
18>             set log_archive_config='dg_config=(dg1,dg2)'
19>             set log_archive_dest_2='service=dg1 ASYNC valid_for=(ONLINE_LOGFILE,PRIMARY_ROLE) db_unique_name=dg1'
20>      ;
21>      }

using target database control file instead of recovery catalog
allocated channel: prmy1
channel prmy1: SID=34 device type=DISK

allocated channel: prmy2
channel prmy2: SID=1169 device type=DISK

allocated channel: prmy3
channel prmy3: SID=33 device type=DISK

allocated channel: prmy4
channel prmy4: SID=1167 device type=DISK

allocated channel: stby
channel stby: SID=10 device type=DISK

Starting Duplicate Db at 16-APR-11

contents of Memory Script:
{
   backup as copy reuse
   targetfile  '/data/oracle/11.2.0/dbhome_1/dbs/orapwdg1' auxiliary format
 '/data/oracle/11.2.0/dbhome_1/dbs/orapwdg2'   targetfile
 '/data/oracle/11.2.0/dbhome_1/dbs/spfiledg1.ora' auxiliary format
 '/data/oracle/11.2.0/dbhome_1/dbs/spfiledg2.ora'   ;
   sql clone "alter system set spfile= ''/data/oracle/11.2.0/dbhome_1/dbs/spfiledg2.ora''";
}
executing Memory Script

Starting backup at 16-APR-11
Finished backup at 16-APR-11

sql statement: alter system set spfile= ''/data/oracle/11.2.0/dbhome_1/dbs/spfiledg2.ora''

contents of Memory Script:
{
   sql clone "alter system set  audit_file_dest =
 ''/data/oracle/admin/dg2/adump'' comment=
 '''' scope=spfile";
   sql clone "alter system set  db_unique_name =
 ''dg2'' comment=
 '''' scope=spfile";
   sql clone "alter system set  db_file_name_convert =
 ''/dg1/'', ''/dg2/'' comment=
 '''' scope=spfile";
   sql clone "alter system set  log_file_name_convert =
 ''/dg1/'', ''/dg2/'' comment=
 '''' scope=spfile";
   sql clone "alter system set  control_files =
 ''/data/oracle/oradata/dg2/dg2.ctl'' comment=
 '''' scope=spfile";
   sql clone "alter system set  log_archive_max_processes =
 5 comment=
 '''' scope=spfile";
   sql clone "alter system set  fal_client =
 ''dg2'' comment=
 '''' scope=spfile";
   sql clone "alter system set  fal_server =
 ''dg1'' comment=
 '''' scope=spfile";
   sql clone "alter system set  standby_file_management =
 ''AUTO'' comment=
 '''' scope=spfile";
   sql clone "alter system set  log_archive_config =
 ''dg_config=(dg1,dg2)'' comment=
 '''' scope=spfile";
   sql clone "alter system set  log_archive_dest_2 =
 ''service=dg1 ASYNC valid_for=(ONLINE_LOGFILE,PRIMARY_ROLE) db_unique_name=dg1'' comment=
 '''' scope=spfile";
   shutdown clone immediate;
   startup clone nomount;
}
executing Memory Script

sql statement: alter system set  audit_file_dest =  ''/data/oracle/admin/dg2/adump'' comment= '''' scope=spfile

sql statement: alter system set  db_unique_name =  ''dg2'' comment= '''' scope=spfile

sql statement: alter system set  db_file_name_convert =  ''/dg1/'', ''/dg2/'' comment= '''' scope=spfile

sql statement: alter system set  log_file_name_convert =  ''/dg1/'', ''/dg2/'' comment= '''' scope=spfile

sql statement: alter system set  control_files =  ''/data/oracle/oradata/dg2/dg2.ctl'' comment= '''' scope=spfile

sql statement: alter system set  log_archive_max_processes =  5 comment= '''' scope=spfile

sql statement: alter system set  fal_client =  ''dg2'' comment= '''' scope=spfile

sql statement: alter system set  fal_server =  ''dg1'' comment= '''' scope=spfile

sql statement: alter system set  standby_file_management =  ''AUTO'' comment= '''' scope=spfile

sql statement: alter system set  log_archive_config =  ''dg_config=(dg1,dg2)'' comment= '''' scope=spfile

sql statement: alter system set  log_archive_dest_2 =  ''service=dg1 ASYNC valid_for=(ONLINE_LOGFILE,PRIMARY_ROLE) db_unique_name=dg1'' comment= '''' scope=spfile

Oracle instance shut down

connected to auxiliary database (not started)
Oracle instance started

Total System Global Area     471830528 bytes

Fixed Size                     2214456 bytes
Variable Size                268436936 bytes
Database Buffers             192937984 bytes
Redo Buffers                   8241152 bytes
allocated channel: stby
channel stby: SID=9 device type=DISK

contents of Memory Script:
{
   backup as copy current controlfile for standby auxiliary format  '/data/oracle/oradata/dg2/dg2.ctl';
}
executing Memory Script

Starting backup at 16-APR-11
channel prmy1: starting datafile copy
copying standby control file
output file name=/data/oracle/11.2.0/dbhome_1/dbs/snapcf_dg1.f tag=TAG20110416T194634 RECID=4 STAMP=748640795
channel prmy1: datafile copy complete, elapsed time: 00:00:01
Finished backup at 16-APR-11

contents of Memory Script:
{
   sql clone 'alter database mount standby database';
}
executing Memory Script

sql statement: alter database mount standby database

contents of Memory Script:
{
   set newname for tempfile  1 to
 "/data/oracle/oradata/dg2/temp01.dbf";
   switch clone tempfile all;
   set newname for datafile  1 to
 "/data/oracle/oradata/dg2/system01.dbf";
   set newname for datafile  2 to
 "/data/oracle/oradata/dg2/sysaux01.dbf";
   set newname for datafile  3 to
 "/data/oracle/oradata/dg2/undotbs01.dbf";
   set newname for datafile  4 to
 "/data/oracle/oradata/dg2/users01.dbf";
   backup as copy reuse
   datafile  1 auxiliary format
 "/data/oracle/oradata/dg2/system01.dbf"   datafile
 2 auxiliary format
 "/data/oracle/oradata/dg2/sysaux01.dbf"   datafile
 3 auxiliary format
 "/data/oracle/oradata/dg2/undotbs01.dbf"   datafile
 4 auxiliary format
 "/data/oracle/oradata/dg2/users01.dbf"   ;
   sql 'alter system archive log current';
}
executing Memory Script

executing command: SET NEWNAME

renamed tempfile 1 to /data/oracle/oradata/dg2/temp01.dbf in control file

executing command: SET NEWNAME

executing command: SET NEWNAME

executing command: SET NEWNAME

executing command: SET NEWNAME

Starting backup at 16-APR-11
channel prmy1: starting datafile copy
input datafile file number=00001 name=/data/oracle/oradata/dg1/system01.dbf
channel prmy2: starting datafile copy
input datafile file number=00002 name=/data/oracle/oradata/dg1/sysaux01.dbf
channel prmy3: starting datafile copy
input datafile file number=00003 name=/data/oracle/oradata/dg1/undotbs01.dbf
channel prmy4: starting datafile copy
input datafile file number=00004 name=/data/oracle/oradata/dg1/users01.dbf
output file name=/data/oracle/oradata/dg2/users01.dbf tag=TAG20110416T194641
channel prmy4: datafile copy complete, elapsed time: 00:00:03
output file name=/data/oracle/oradata/dg2/undotbs01.dbf tag=TAG20110416T194641
channel prmy3: datafile copy complete, elapsed time: 00:00:36
output file name=/data/oracle/oradata/dg2/system01.dbf tag=TAG20110416T194641
channel prmy1: datafile copy complete, elapsed time: 00:00:56
output file name=/data/oracle/oradata/dg2/sysaux01.dbf tag=TAG20110416T194641
channel prmy2: datafile copy complete, elapsed time: 00:00:56
Finished backup at 16-APR-11

sql statement: alter system archive log current

contents of Memory Script:
{
   switch clone datafile all;
}
executing Memory Script

datafile 1 switched to datafile copy
input datafile copy RECID=4 STAMP=748640857 file name=/data/oracle/oradata/dg2/system01.dbf
datafile 2 switched to datafile copy
input datafile copy RECID=5 STAMP=748640857 file name=/data/oracle/oradata/dg2/sysaux01.dbf
datafile 3 switched to datafile copy
input datafile copy RECID=6 STAMP=748640857 file name=/data/oracle/oradata/dg2/undotbs01.dbf
datafile 4 switched to datafile copy
input datafile copy RECID=7 STAMP=748640857 file name=/data/oracle/oradata/dg2/users01.dbf
Finished Duplicate Db at 16-APR-11
released channel: prmy1
released channel: prmy2
released channel: prmy3
released channel: prmy4
released channel: stby

RMAN>

Artık dataguardımız hazır sayılır. Bize kalan sadece apply başlatmak için komutumuzu çalıştırmak. Standby sunucusu üzerine gidip komutumuzu başlatalım;
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;

Database altered.

Artık dataguardımız hazır sayılır. Şimdi primary ile karşılaştırıp kontrol edelim.
-- Çıkan logları kontrol etmek için;

SQL> SELECT SEQUENCE#, FIRST_TIME, NEXT_TIME 
  2  FROM V$ARCHIVED_LOG
  3  ORDER BY SEQUENCE# desc;

 SEQUENCE# FIRST_TIM NEXT_TIME
---------- --------- ---------
        98 16-APR-11 16-APR-11
        98 16-APR-11 16-APR-11
        97 16-APR-11 16-APR-11
        97 16-APR-11 16-APR-11
        96 16-APR-11 16-APR-11
        96 16-APR-11 16-APR-11
        95 16-APR-11 16-APR-11
        95 16-APR-11 16-APR-11
        94 16-APR-11 16-APR-11
        94 16-APR-11 16-APR-11
        93 16-APR-11 16-APR-11

-- Standby tarafında çıkan logların durumunu kontrol etmek için;

SQL> SELECT SEQUENCE#, FIRST_TIME, NEXT_TIME
FROM V$ARCHIVED_LOG
ORDER BY SEQUENCE# desc ;

 SEQUENCE# FIRST_TIM NEXT_TIME
---------- --------- ---------
        98 16-APR-11 16-APR-11
        97 16-APR-11 16-APR-11
        96 16-APR-11 16-APR-11
        95 16-APR-11 16-APR-11
        94 16-APR-11 16-APR-11
        93 16-APR-11 16-APR-11
        92 16-APR-11 16-APR-11
        91 16-APR-11 16-APR-11
        90 16-APR-11 16-APR-11
        89 16-APR-11 16-APR-11
        88 16-APR-11 16-APR-11

-- Standbyda hangilerinin apply olduğunu görebilmek içinse;

SQL> SELECT SEQUENCE#,APPLIED FROM V$ARCHIVED_LOG ORDER BY SEQUENCE# desc ;

 SEQUENCE# APPLIED
---------- ---------
        98 IN-MEMORY
        97 YES
        96 YES
        95 YES
        94 YES
        93 YES
        92 YES
        91 YES
        90 YES
        89 YES
        88 YES

Çıkan tüm archiveların apply olduğunu görebiliyoruz.  11gR2 için dataguard kurulumunun adım adım  nasıl yapabileceğimizi ifade etmeye çalıştım.Umarım  faydalı olmuştur.



 Kamil TÜRKYILMAZ