DoubleDBDeep

[ORACLE] Active Data Guard 본문

ORACLE/OGG | ADG

[ORACLE] Active Data Guard

DBCAMI 2023. 5. 15. 14:11

참고 docs

https://docs.oracle.com/en/database/oracle/oracle-database/19/sbydb/oracle-data-guard-concepts.html#GUID-F78703FB-BD74-4F20-9971-8B37ACC40A65

 

Concepts and Administration

 

docs.oracle.com

ADG

- Standby Database (DR DB)를 생성하여 운영 데이터베이스를 재해 및 장애상황에서 살아남을 수 있도록 하는 기능

- Data Guard는 Production Database (Primary DB)의 복사본으로 유지 및 관리

- OGG의 하위버전이라 생각하면 된다 

(23/12/09) 하위버전 .... ?? ㅇㅋ.., 어쨌든 둘다 Log Mining 기능을 사용하는 것은 같고 어느 기능이 더 뛰어나다 할건 모르겠지만, 사용 목적에 따라 다를듯 adg는 DB 통째로 적용되는데 OGG는 테이블마다 각각 설정 할 수 있다는 것이 다르고

ADG는 Snapshot database의 기능으로 또하나의 다른 버전의 같은 DB를 만들 수 있다는 점이 다르다

--> 여기서 DG랑 차이점이 나타나는건데, ADG는 Snapshot DB로 새로운 버전의 DB를 다시 올릴 수 있고 DG는 그렇겐 사용할 수 없다는 점에서 다름~ (오픈안댐)

 

- RMAN의 Duplicate 명령을 통해 단방향 데이터 복제가 진행되고, Standby에서 전달받은 데이터를 스토리지에 적재하는 동작 원리이다.

 

Configuration

Primary Database

= production database = 운영 데이터베이스

- Primary database는 Single Oracle Database , RAC Database 모두 가능함.

- Read / Write 상태가 됨

 

Standby Database

= primary database의 복사본

최대 30개의 standby database를 생성하여 ADG에 통합할 수 있다.

Data Guard는 Primary Database에서 redo 데이터를 Standby Database에 적용하여 자동으로 유지 관리함

- Standby database는 Single Oracle Database , RAC Database 모두 가능함.

- Read Only 상태가 됨

 

Standby Database의 2가지 타입

1. 물리적 Standby 데이터베이스 (Physical Standby Database)

: primary database block-for-block / 물리적으로 완전히 동일한 복사본으로, Redo Apply 프로세스에 의해 정확한 복사본을 전송받아 적용하는 방식으로 동기화가 관리된다.

 

장점 

- DR 및 고가용성 : primary <-> Standby 간 역할 전환을 쉽게 수행할 수 있고, 다운타임 최소화 가능

- 데이터 보호 : 재해상황에서 데이터 손실 방지

- 워크로드 감소 : RMAN이 physical standby db를 오프로드 백업으로 사용하여 CPU 및 I/O 주기 절약

- 성능 by Redo Apply 기술

 

2. 논리적 Standby  데이터베이스 (Logical Standby Database)

: 로그파일의 데이터를 SQL문으로 변환 후 Stanby Database에서 해당 SQL문을 실행하여 데이터베이스를 업데이트 하는 방식 

 

Operational Prerequisties (사전 요구사항)

1. 하드웨어 및 OS 요구사항

- primary , standby database는 서로 동일한 릴리스의 Oracle Database Enterprise Edition 이어야 함.

- 11g 부터 Data Guard는 서로 다른 CPU, OS, Binaries(32bit <-> 64bit)를 유연하게 제공함 !

 

2. 오라클 소프트웨어 요구사항

- 각 Database들의 COMPATIBLE 초기화 파라미터가 동일해야함

- Primary Database는 ARCHIVELOG 모드여야 함

- Primary Database를 direct writes에서 보호하기 위해 FORCE LOGGING 모드로 설정해야 함

- ASM을 사용하는 경우 Primary와 Standby가 대칭적으로 구성되어 있는 것을 권장 (크기, 파일경로, 네이밍 규칙 등)

- 두 database 서버의 시간대가 동일하게 설정하는 것을 권장

 


사전작업

1. Primary Database 생성

2023.03.23 - [ORACLE/INSTALL] - [ORACLE] Oracle Database 19c RAC 설치 & 19.17 patch

 

[ORACLE] Oracle Database 19c RAC 설치 & 19.17 patch

ADG test를 위한 19.17 oracle RAC 설치 (Standby DB server) OS / ORACLE ENVIRONMENT EDITION EE RAC RAC 2 NODE VERSION Oracle Database19c PATCH 34416665 (19.17.0.0.0) SERVER Linux 7.9 (5.4.17-2102.201.3.el7uek.x86_64) Media 준비 - 엔진 : https://www.

devcami.tistory.com

위 글과 같은 구성으로 생성했음

 

2. Data Guard 환경 설정

force_logging 설정 - primary db
SQL> select force_logging, supplemental_log_data_min from v$database;

FORCE_LOGGING				SUPPLEME
--------------------------------------- --------
NO					NO

SQL> alter database force logging;

Database altered.

SQL> alter database add supplemental log data ;

Database altered.

SQL> select force_logging, supplemental_log_data_min from v$database;

FORCE_LOGGING				SUPPLEME
--------------------------------------- --------
YES					YES

 

archive log mode 설정 - primary db
SQL> select log_mode from v$database;

LOG_MODE
------------
NOARCHIVELOG

SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount
ORACLE instance started.

Total System Global Area 3120558872 bytes
Fixed Size		    8901400 bytes
Variable Size		  721420288 bytes
Database Buffers	 2382364672 bytes
Redo Buffers		    7872512 bytes
Database mounted.
SQL> alter database archivelog;

Database altered.

SQL> alter database open;

Database altered.

SQL> select log_mode from v$database;

LOG_MODE
------------
ARCHIVELOG

 

standby redo log 생성 - primary db
# Primary 현재 redo log 확인
select l.group#, l.thread#, f.member, l.archived, l.status, (bytes/1024/1024) "Size (MB)"
from v$log l, v$logfile f 
where f.group# = l.group# 
order by 1,2;
# Standby redo log 생성
## ASM Directory 생성
alter diskgroup DATA add directory '+DATA/RAC/ADG' ; 

## redo log 생성 / fra 파일 제외하고 thread 당 group + 1개
alter database add standby logfile thread 1 size 200m ;
alter database add standby logfile thread 1 size 200m ;
alter database add standby logfile thread 1 size 200m ;								
alter database add standby logfile thread 1 size 200m ;
alter database add standby logfile thread 1 size 200m ;

alter database add standby logfile thread 2 size 200m ;
alter database add standby logfile thread 2 size 200m ;
alter database add standby logfile thread 2 size 200m ;
alter database add standby logfile thread 2 size 200m ;
alter database add standby logfile thread 2 size 200m ;

# 생성 확인
select * 
from v$logfile
where type='STANDBY';

 

password 파일 복사 - primary db (rac1, rac2)
asmcmd -p
pwget --dbuniquename rac
+DATA/RAC/PASSWORD/pwdrac.256.1136382787
pwcopy '+DATA/RAC/PASSWORD/pwdrac.256.1136382787' '/tmp/orapwRAC'
copying +DATA/RAC/PASSWORD/pwdrac.256.1136382787 -> /tmp/orapwRAC

# 확인
cd /tmp
ls -al | grep orapw

[+ASM2|grid:/tmp]> ls -al | grep orapw
-rw-r-----.  1 grid   oinstall   2048 May 10 10:05 orapwRAC

# standby로 전송
scp -pr /tmp/orapwRAC oracle@10.0.5.103:/u01/app/oracle/product/19.0.0/dbhome_1/dbs/orapwRACDR1
scp -pr /tmp/orapwRAC oracle@10.0.5.104:/u01/app/oracle/product/19.0.0/dbhome_1/dbs/orapwRACDR2

 

parameter 변경 - primary db / standby db

primary db

parameter 수정

- db_name : primary, standby가 동일한 값을 가져야 함

- db_unique_name : primary(rac), standby(racdr) 구분을 위해 별도로 지정

# rac (primary)
alter system set LOG_ARCHIVE_CONFIG='DG_CONFIG=(rac,racdr)' scope=both sid='*';
alter system set LOG_ARCHIVE_DEST_STATE_1=ENABLE scope=both sid='*';
alter system set LOG_ARCHIVE_DEST_STATE_2=DEFER scope=both sid='*';
alter system set LOG_ARCHIVE_DEST_1='LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=rac' scope=both sid='rac1';
alter system set LOG_ARCHIVE_DEST_1='LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=rac' scope=both sid='rac2';
alter system set LOG_ARCHIVE_DEST_2='SERVICE=racdr LGWR ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=racdr' scope=both sid='rac1';
alter system set LOG_ARCHIVE_DEST_2='SERVICE=racdr LGWR ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=racdr' scope=both sid='rac2';
alter system set FAL_SERVER='racdr' scope=both sid='*';
alter system set FAL_CLIENT=rac1 scope=both sid='rac1';
alter system set FAL_CLIENT=rac2 scope=both sid='rac2';
ALTER SYSTEM SET STANDBY_FILE_MANAGEMENT=AUTO;

 

standby db

pfile 생성

# standby pfile 수정
vi $ORACLE_HOME/dbs/initracdr1.ora

##############################################
# ADG (STANDBY)
##############################################
*.control_files='+DATA/RAC/CONTROLFILE/current.317.1136382807'
*.audit_file_dest='/u01/app/oracle/admin/racdr/adump'
*.audit_trail='db'
*.compatible='19.0.0'
*.db_name='rac'
*.db_unique_name='racdr'
*.db_recovery_file_dest='+FRA'
*.db_recovery_file_dest_size=8451m
*.service_names='rac','racdr'
*.fal_client='racdr'
*.fal_server='rac'
*.log_archive_config='dg_config=(rac,racdr)'
*.log_archive_dest_1='LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=racdr'
*.log_archive_dest_2='service=rac ASYNC valid_for=(ONLINE_LOGFILE,PRIMARY_ROLE) db_unique_name=rac'
*.LOG_ARCHIVE_DEST_STATE_2=defer
*.standby_file_management='AUTO'
# ASM에서는 사용 x
#*.db_file_name_convert='+DATA/RAC/','+DATA/RACDR/'
#*.log_file_name_convert='+FRA/RAC/','+FRA/RACDR/'

#*.local_listener='(DESCRIPTION=(ADDRESS=(PROTOCOL = TCP)(HOST = 10.0.5.103)(PORT = 1721))(ADDRESS=(PROTOCOL = TCP)(HOST = 10.0.5.104)(PORT = 1721)))'

 

adump 디렉토리 생성 - standby

- standby db pfile에 작성한 adump 물리적 directory 생성 (안하면 오류남)

mkdir -p /u01/app/oracle/admin/racdr/adump
chmod -R 750 /u01/app/oracle/admin/racdr

ls -al /u01/app/oracle/admin/racdr

 

 

ASM 디렉토리 생성 - standby / grid
asmcmd -p
cd +DATA
mkdir RACDR
cd +FRA
mkdir RACDR

 

2. 네트워크 환경 설정

Listener 생성 및 시작 - standby db
vi $ORACLE_HOME/network/admin/listener.ora
# node 1
LISTENER_RACDR1 =
 (DESCRIPTION_LIST =
  (DESCRIPTION =
   (ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.5.103)(PORT = 1721))
  )
  (DESCRIPTION =
   (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1721)))
  )
 )

SID_LIST_LISTENER_RACDR1 =
  (SID_LIST =
    (SID_DESC =
      (GLOBAL_DBNAME = racdr)
      (SID_NAME = racdr1)
      (ORACLE_HOME = /u01/app/oracle/product/19.0.0/dbhome_1)
    )
  )

# node 2
LISTENER_RACDR2 =
 (DESCRIPTION_LIST =
  (DESCRIPTION =
   (ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.5.104)(PORT = 1721))
  )
  (DESCRIPTION =
   (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1721)))
  )
 )

SID_LIST_LISTENER_RACDR2 =
  (SID_LIST =
    (SID_DESC =
      (GLOBAL_DBNAME = racdr)
      (SID_NAME = racdr2)
      (ORACLE_HOME = /u01/app/oracle/product/19.0.0/dbhome_1)
    )
  )
  
lsnrctl start LISTENER_RACDR1
lsnrctl start LISTENER_RACDR2

 

TNS 수정 - primary, standby db

primary db

vi $ORACLE_HOME/network/admin/tnsnames.ora
RAC =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = rac-scan)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = rac)
    )
  )
RACDR =
  (DESCRIPTION =
  (ADDRESS_LIST =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.5.103)(PORT = 1721))
    (ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.5.104)(PORT = 1721)))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = racdr)
    )
  )

standby db

vi $ORACLE_HOME/network/admin/tnsnames.ora
RAC =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.5.101)(PORT = 1521))
    (ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.5.102)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = rac)
    )
  )
RACDR =
  (DESCRIPTION =
  (ADDRESS_LIST =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.5.103)(PORT = 1721))
    (ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.5.104)(PORT = 1721)))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = racdr)
    )
  )

 


본작업

1. Standby DB nomount startup

- 사전작업에서 생성한 pfile로 nomount startup 해준다

startup nomount pfile='/u01/app/oracle/product/19.0.0/dbhome_1/dbs/initracdr1.ora'

 

2. RMAN Duplicate을 사용하여 Standby DB 생성 - standby

RMAN 접속
rman target sys/oracle@RAC auxiliary sys/oracle@RACDR

 

RMAN Duplicate으로 DB 생성

- set newname으로 file명을 지정하지 않을 시 ORA-10458 ORA-01152 ORA-01110 관련 오류 발생 가능

run {
allocate channel prmy1 type disk;
allocate channel prmy2 type disk;
allocate auxiliary channel stby type disk;
set newname for DATAFILE 1 to '+DATA/RACDR/DATAFILE/system01';
set newname for DATAFILE 2 to '+DATA/RACDR/DATAFILE/sysaux01';
set newname for DATAFILE 3 to '+DATA/RACDR/DATAFILE/undotbs1';
set newname for DATAFILE 4 to '+DATA/RACDR/DATAFILE/undotbs2';
set newname for DATAFILE 5 to '+DATA/RACDR/DATAFILE/users01';
set newname for TEMPFILE 1 to '+DATA/RACDR/TEMPFILE/temp01';
duplicate target database for standby from active database 
nofilenamecheck;
}

 

완료 후 확인
SQL> show parameter db_name

NAME				     TYPE	 VALUE
------------------------------------ ----------- ------------------------------
db_name 			     string	 rac


SQL> select instance_name, status from v$instance ;

INSTANCE_NAME	 STATUS
---------------- ------------
racdr1		 MOUNTED


SQL> select database_role, open_mode from v$database;

DATABASE_ROLE	 OPEN_MODE
---------------- --------------------
PHYSICAL STANDBY MOUNTED

 

 

3. 로그 전송 시작 - primary

- parameter # LOG_ARCHIVE_DEST_STATE_2 활성화

alter system set LOG_ARCHIVE_DEST_STATE_2=ENABLE scope=both sid='*';

 

4. database 복구  - standby

- duplicate 후 archive log를 적용하여 database 완전복구

sqlplus / as sysdba
recover standby database ;

Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
ORA-00279: change [000000] ~~~


# archive file 조회 - primary
select thread#, FIRST_CHANGE#, NEXT_CHANGE#, name
from v$archived_log
where [000000] between FIRST_CHANGE# and NEXT_CHANGE# ;

# primary에서 조회된 archive file을 직접 옮겨 적용시킴
# no longer needed for this recovery 나오면 cancel

 

5. 실시간 동기화

동기화 복구 수행
# Redo apply 시작
# disconnect : 완료되지 않아도 백그라운드에서 진행하고 프롬프트를 사용하기 위한 옵션

alter database recover managed standby database disconnect;
또는
alter database recover managed standby database using archived logfile disconnect;

# Real-Time Apply를 사용한 Redo Data 즉시 적용 - using current logfile절 
# 12.1c 이후로는 해당 절 사용하지 않아도 Real-Time Apply가 자동으로 적용됨. 
alter database recover managed standby database using current logfile disconnect;
동기화 종료
# Redo 적용 중지
alter database recover managed standby database cancel;
DB Open 및 실시간 동기화 시작
alter database open ;
alter database recover managed standby database [using current logfile] disconnect;
확인
# mrp 조회
select process, status, THREAD#,sequence#, block#, blocks, delay_mins from v$managed_standby;

# database role 조회
select database_role, open_mode from v$database;

DATABASE_ROLE	 OPEN_MODE
---------------- --------------------
PHYSICAL STANDBY READ ONLY WITH APPLY

 

6. 동기화 체크

  • GAP 차이 (value) 조회
set line 200 pages 1000
col NAME for a30
col VALUE for a30
col UNIT for a30
col TIME_COMPUTED for a25
select NAME,VALUE,UNIT,TIME_COMPUTED from v$dataguard_stats;


# VALUE 값이 존재해야 함.
NAME			       VALUE			      UNIT			     TIME_COMPUTED
------------------------------ ------------------------------ ------------------------------ -------------------------
transport lag		       +00 00:00:00		      day(2) to second(0) interval   05/11/2023 04:47:46
apply lag		       +00 00:00:00		      day(2) to second(0) interval   05/11/2023 04:47:46
apply finish time	       +00 00:00:00.000 	      day(2) to second(3) interval   05/11/2023 04:47:46
estimated startup time	       19			      second			     05/11/2023 04:47:46
  • Primary에서 데이터 수정 후 commit 시 Standby에 적용 확인
select table_name from dba_tables where owner='SAMPLE';
select count(*) from SAMPLE.EMPLOYEES ;
DELETE FROM SAMPLE.EMPLOYEES WHERE EMPLOYEE_ID=105 ;
COMMIT ;
  • Primary에서 Log Switch 발생 후 Standby에서 생성 확인
alter system switch logfile ;

# archive log file 생성 확인 - standby
SELECT sequence#, first_time, next_time, status
FROM GV$ARCHIVED_LOG
ORDER BY 1 ;

사후작업

1. Standby Database CRS 등록 - RAC의 경우

alter system set cluster_database=TRUE scope=spfile sid='*';
alter system set instance_number=1 scope=spfile sid='racdr1';
# Cluster Parameter 수정
alter system set instance_number=2 scope=spfile sid='racdr2';
alter system set thread=1 scope=spfile sid='racdr1' ;
alter system set thread=2 scope=spfile sid='racdr2' ;
alter system set undo_tablespace='UNDOTBS1' scope=spfile sid='racdr1' ;
alter system set undo_tablespace='UNDOTBS2' scope=spfile sid='racdr2' ;
alter system set service_names='rac','racdr' sid='*' scope=both ;
alter system set local_listener='(DESCRIPTION=(ADDRESS=(PROTOCOL = TCP)(HOST = 10.0.5.103)(PORT = 1721)))' sid='racdr1' scope=both ;
alter system set local_listener='(ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.5.104)(PORT = 1721))' sid='racdr2' scope=both ;


# Database 추가
srvctl add database -db rac -dbname racdr -oraclehome /u01/app/oracle/product/19.0.0/dbhome_1 -role physical_standby
srvctl add instance -d rac -i racdr1 -node racdr1
srvctl add instance -d rac -i racdr2 -node racdr2

# 2번 node로 spfile 전송
scp $ORACLE_HOME/dbs/spfileracdr1.ora oracle@10.0.5.104:/u01/app/oracle/product/19.0.0/dbhome_1/dbs/spfileracdr1.ora
srvctl modify database -d rac -spfile /u01/app/oracle/product/19.0.0/dbhome_1/dbs/spfileracdr1.ora

# database 구성 확인
srvctl config database -d rac

# crs 등록 확인
crsctl stat res -t

2. spfile을 ASM DISK로 변경

# 현재 pfile 백업
mv initracdr1.ora initracdr1.ora.org

# 새로운 spfile 생성
create pfile from spfile ;
create spfile='+DATA/RACDR/PARAMETERFILE/spfileracdr' from pfile ;

# crs 정보에 spfile 새로 등록
mv spfileracdr1.ora spfileracdr1.ora.bk
srvctl modify database -d rac -spfile +DATA/RACDR/PARAMETERFILE/spfileracdr

# 확인
srvctl config database -d rac

# 재기동
srvctl stop database -d rac
srvctl start database -d rac

3. 컨트롤파일 이중화(또는 3중화)

- Primary와 동일하게 맞춰주면 된다.

# nomount - node 2는 shut 상태유지
shut immediate
startup nomount

# 기존 control file 복사 - RMAN
rman target /
restore controlfile to '+FRA' from '+DATA/RACDR/CONTROLFILE/current.270.1136519473';


RMAN> restore controlfile to '+FRA' from '+DATA/RACDR/CONTROLFILE/current.270.1136519473';

Starting restore at 2023/05/15 13:54:33
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=30 instance=racdr1 device type=DISK

channel ORA_DISK_1: copied control file copy
Finished restore at 2023/05/15 13:54:36

ASMCMD [+FRA/RACDR/CONTROLFILE] > ls -l
Type         Redund  Striped  Time             Sys  Name
CONTROLFILE  UNPROT  FINE     MAY 15 13:00:00  Y    current.289.1136901275


# 파라미터 변경
alter system set control_files='+DATA/RACDR/CONTROLFILE/current.270.1136519473','+FRA/RACDR/CONTROLFILE/current.289.1136901275' scope=spfile ;

# 재기동
shut immediate
srvctl start database -d rac

 

 

728x90