카테고리 없음

10. Oracle 데이터가드 구현하기

개인공부 2026. 3. 28. 01:17

 

[개발 환경]

  • Oracle 19C Enterprise Edition
  • Oracle VirtualBox
  • MobatXterm 

 

 

Oracle 데이터가드의 중요성

Oracle 데이터가드(Data Guard)는 기업의 핵심 자산인 데이터를 보호하고, 어떤 상황에서도 서비스 연속성을 유지하기 위해 필수적인 솔루션입니다. 단순히 백업을 하는 수준을 넘어, 시스템 장애나 재해 발생 시 즉각적으로 대응할 수 있는 고가용성(High Availability) 환경을 구축하는 것이 핵심입니다.

데이터가드가 왜 중요한지 주요 관점별로 정리해 드립니다.


1. 비즈니스 연속성 유지 (Disaster Recovery)

가장 큰 이유는 재해 복구입니다. 주 서버(Primary Database)에 화재, 정전, 하드웨어 고장이 발생하더라도 원격지에 있는 대기 서버(Standby Database)로 서비스를 즉시 전환(Failover)할 수 있습니다.

  • 복구 시간 단축(RTO): 장애 발생 시 수분 내로 서비스를 정상화할 수 있습니다.
  • 데이터 손실 최소화(RPO): 실시간 데이터 동기화를 통해 데이터 유실을 0에 가깝게 방지합니다.

2. 데이터 보호 및 무결성 검증

데이터가드는 주 서버의 변경 사항(Redo Log)을 대기 서버로 전송하여 반영합니다. 이 과정에서 전송된 데이터가 손상되었는지 확인하는 프로세스가 포함되어 있어, 데이터 부패(Data Corruption)로부터 안전하게 데이터를 보호합니다.

3. 주 서버의 부하 분산 (Offloading)

대기 서버를 단순히 '노는 서버'로 두지 않고 활용할 수 있다는 점이 큰 장점입니다. 이를 Active Data Guard라고 부릅니다.

  • 읽기 전용 질의: 조회 업무나 복잡한 리포트 출력 작업을 대기 서버에서 수행하여 주 서버의 CPU/메모리 부하를 줄입니다.
  • 백업 수행: 대기 서버에서 백업을 수행함으로써 주 서버의 성능 저하 없이 안정적인 백업본을 확보할 수 있습니다.

4. 계획된 작업 시 다운타임 최소화

운영체제 패치, 하드웨어 업그레이드, 데이터베이스 업그레이드 등 계획된 유지보수 작업을 할 때 유용합니다.

  • Switchover: 장애 상황이 아니더라도 주 서버와 대기 서버의 역할을 전환할 수 있습니다. 대기 서버를 먼저 업그레이드한 후 역할을 전환하면 서비스 중단 시간을 최소화(Zero or Near-Zero Downtime)하며 작업을 마칠 수 있습니다.
  •  

 

1. Primary DB 구현하기

 

1-1. .bash_profile 수정하기

oracle@localhost ~]$ vi .bash_profile

[oracle@localhost ~]$ cat .bash_profile
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/.local/bin:$HOME/bin
export ORACLE_BASE=/u01/app/oracle
export ORACLE_HOME=/u01/app/oracle/product/19c/dbhome_1
export ORA_INVENTORY=/u01/app/oraInventory
export ORACLE_SID=PROD
#export TNS_ADMIN=/u01/app/oracle/product/19.3.0/dbhome_1/network/admin
export PATH=$PATH:$HOME/bin:$ORACLE_HOME/bin
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib
export CLASSPATH=$ORACLE_HOME/JRE:$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib
# 리눅스 시스템 언어 설정 (영문으로 통일)
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
# 오라클 언어 설정 (영문/UTF-8)
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
export PATH
alias sys='sqlplus / as sysdba'
alias alert='tail -f $ORACLE_BASE/diag/rdbms/prod/PROD/trace/alert_PROD.log'
export PATH

[oracle@localhost ~]$ source .bash_profile

[oracle@localhost ~]$ echo $ORACLE_SID
PROD

 

 

1-2 Database를 생성할 디렉토리 생성하기

[oracle@localhost ~]$ mkdir -p /u01/app/oracle/oradata/PROD
[oracle@localhost ~]$
[oracle@localhost ~]$ cd /u01/app/oracle/oradata/PROD
[oracle@localhost PROD]$ pwd
/u01/app/oracle/oradata/PROD
[oracle@localhost PROD]$
[oracle@localhost PROD]$ mkdir disk1 disk2 disk3 disk4 disk5
[oracle@localhost PROD]$
[oracle@localhost PROD]$ ls
disk1  disk2  disk3  disk4  disk5

 

1-3 Parameter file 생성하기

[oracle@localhost ~]$ vi $ORACLE_HOME/dbs/initPROD.ora

[oracle@localhost ~]$ cat > $ORACLE_HOME/dbs/initPROD.ora << 'EOF'
> db_name=PROD
> compatible=19.3.0
> memory_target=1G
> processes=300
> undo_management=AUTO
> undo_tablespace=UNDOTBS1
> remote_login_passwordfile=EXCLUSIVE
> db_unique_name=PROD
> control_files=('/u01/app/oracle/oradata/PROD/disk1/ctrl1.ctl',
>                '/u01/app/oracle/oradata/PROD/disk2/ctrl2.ctl',
>                '/u01/app/oracle/oradata/PROD/disk3/ctrl3.ctl')
> EOF

[oracle@localhost ~]$ cat $ORACLE_HOME/dbs/initPROD.ora
db_name=PROD
compatible=19.3.0
memory_target=1G
processes=300
undo_management=AUTO
undo_tablespace=UNDOTBS1
remote_login_passwordfile=EXCLUSIVE
db_unique_name=PROD
control_files=('/u01/app/oracle/oradata/PROD/disk1/ctrl1.ctl',
               '/u01/app/oracle/oradata/PROD/disk2/ctrl2.ctl',
               '/u01/app/oracle/oradata/PROD/disk3/ctrl3.ctl')

 

1-4 DB를 nomount로 실행하고 인스턴스를 확인합니다

SQL> startup nomount pfile=$ORACLE_HOME/dbs/initPROD.ora
ORACLE instance started.

Total System Global Area 1073737800 bytes
Fixed Size                  8904776 bytes
Variable Size             620756992 bytes
Database Buffers          436207616 bytes
Redo Buffers                7868416 bytes
SQL>
SQL> SELECT instance_name, status, database_status FROM v$instance;

INSTANCE_NAME
------------------------------------------------
STATUS
------------------------------------
DATABASE_STATUS
---------------------------------------------------
PROD
STARTED
ACTIVE

 

instance가 보기 힘들게 나오네요. 편의성을 위해 보기좋게 수정하겠습니다.

SQL> COL instance_name FORMAT A15
SQL> COL status FORMAT A10
SQL> COL database_status FORMAT A15

SQL> SELECT instance_name, status, database_status FROM v$instance;

INSTANCE_NAME   STATUS     DATABASE_STATUS
--------------- ---------- ---------------
PROD            STARTED    ACTIVE

 

이걸 @instance로 바로 실행이 가능하게 하도록 SQL쿼리문을 만들어주겠습니다.

[oracle@localhost ~]$ cat > /home/oracle/instance.sql << 'EOF'
> COL instance_name FORMAT A15
> COL status FORMAT A10
> COL database_status FORMAT A15
>
> SELECT instance_name, status, database_status FROM v$instance;
> EOF

 

 

한 번에 잘 작동 되네요

 

1-5

Primary DB와 Standby DB를 만들 건데 이미지를 보니 SQL>로 되어있어서 헷갈릴 수도 있을 거 같아요.

SQL@PROD>

SQL@SBDB>로 나오도록 각각 수정할게요

[oracle@localhost ~]$ cd $ORACLE_HOME/sqlplus/admin

[oracle@localhost admin]$ vi glogin.sql

[oracle@localhost admin]$ cat glogin.sql

--
-- Copyright (c) 1988, 2005, Oracle.  All Rights Reserved.
--
-- NAME
--   glogin.sql
--
-- DESCRIPTION
--   SQL*Plus global login "site profile" file
--
--   Add any SQL*Plus commands here that are to be executed when a
--   user starts SQL*Plus, or uses the SQL*Plus CONNECT command.
--
-- USAGE
--   This script is automatically run
SET SQLPROMPT "_USER'@'_CONNECT_IDENTIFIER> "

 

맨 마지막에 SET SGLPOMPT "_USER'@'_CONNECT_IDENTIFIER> "-를 추가해주었어요.

잘 나오네요

 

1-6  Alert log 위치 확인과 실시간 모니터링을 위한 alias도 만들겠습니다.

아래의 코드를 .bash_profile에 넣어주겠습니다.

alias palert='tail -f /u01/app/oracle/diag/rdbms/prod/PROD/trace/alert_PROD.log'

alias salert='tail -f /u01/app/oracle/diag/rdbms/prod/PROD/trace/alert_PROD.log'

[oracle@localhost ~]$ vi .bash_profile

[oracle@localhost ~]$ cat .bash_profile

# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/.local/bin:$HOME/bin
export ORACLE_BASE=/u01/app/oracle
export ORACLE_HOME=/u01/app/oracle/product/19c/dbhome_1
export ORA_INVENTORY=/u01/app/oraInventory
export ORACLE_SID=PROD
#export TNS_ADMIN=/u01/app/oracle/product/19.3.0/dbhome_1/network/admin
export PATH=$PATH:$HOME/bin:$ORACLE_HOME/bin
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib
export CLASSPATH=$ORACLE_HOME/JRE:$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib
# 리눅스 시스템 언어 설정 (영문으로 통일)
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
# 오라클 언어 설정 (영문/UTF-8)
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
export PATH

alias sys='sqlplus / as sysdba'
alias alert='tail -f $ORACLE_BASE/diag/rdbms/prod/PROD/trace/alert_PROD.log'

alias palert='tail -f /u01/app/oracle/diag/rdbms/prod/PROD/trace/alert_PROD.log'
alias salert='tail -f /u01/app/oracle/diag/rdbms/sbdb/SBDB/trace/alert_SBDB.log'
export PATH

[oracle@localhost ~]$ source .bash_profile

 

1-7 이제 CREATE DATABASE를 진행해주겠습니다.

create database PROD
user sys identified by oracle
user system identified by oracle
datafile '/u01/app/oracle/oradata/PROD/disk1/system01.dbf'
size 100M autoextend on maxsize unlimited extent management local
sysaux
datafile '/u01/app/oracle/oradata/PROD/disk2/sysaux01.dbf'
size 50M autoextend on maxsize unlimited
default temporary tablespace temp
tempfile '/u01/app/oracle/oradata/PROD/disk3/temp01.dbf'
size 50M autoextend on maxsize unlimited
undo tablespace undotbs1
datafile '/u01/app/oracle/oradata/PROD/disk4/undotbs01.dbf'
size 50M autoextend on maxsize unlimited
logfile
group 1 ('/u01/app/oracle/oradata/PROD/disk4/redoG1M1.rdo',
'/u01/app/oracle/oradata/PROD/disk5/redoG1M2.rdo') size 100M,
group 2 ('/u01/app/oracle/oradata/PROD/disk4/redoG2M1.rdo',
'/u01/app/oracle/oradata/PROD/disk5/redoG2M2.rdo') size 100M,
group 3 ('/u01/app/oracle/oradata/PROD/disk4/redoG3M1.rdo',
'/u01/app/oracle/oradata/PROD/disk5/redoG3M2.rdo') size 100M,
group 4 ('/u01/app/oracle/oradata/PROD/disk4/redoG4M1.rdo',
'/u01/app/oracle/oradata/PROD/disk5/redoG4M2.rdo') size 100M,
group 5 ('/u01/app/oracle/oradata/PROD/disk4/redoG5M1.rdo',
'/u01/app/oracle/oradata/PROD/disk5/redoG5M2.rdo') size 100M;

 

확인됐네요.

 

데모스크립트를 진행하겠습니다.

마찬가지로 @demo로 바로 진행이 가능하도록

 vi demo.sql를 스크립트를 만들어주었습니다.

DROP TABLE EMP CASCADE CONSTRAINTS PURGE;
DROP TABLE DEPT CASCADE CONSTRAINTS PURGE;

CREATE TABLE DEPT
       (DEPTNO number(10),
        DNAME VARCHAR2(14),
        LOC VARCHAR2(13)
);

INSERT INTO DEPT VALUES (10, 'ACCOUNTING', 'NEW YORK');
INSERT INTO DEPT VALUES (20, 'RESEARCH',   'DALLAS');
INSERT INTO DEPT VALUES (30, 'SALES',      'CHICAGO');
INSERT INTO DEPT VALUES (40, 'OPERATIONS', 'BOSTON');

CREATE TABLE EMP (
 EMPNO               NUMBER(4) NOT NULL,
 ENAME               VARCHAR2(10),
 JOB                 VARCHAR2(9),
 MGR                 NUMBER(4) ,
 HIREDATE            DATE,
 SAL                 NUMBER(7,2),
 COMM                NUMBER(7,2),
 DEPTNO              NUMBER(2)
 );

INSERT INTO EMP VALUES (7839,'KING','PRESIDENT',NULL,TO_DATE('1981-11-17','YYYY-MM-DD'),5000,NULL,10);
INSERT INTO EMP VALUES (7698,'BLAKE','MANAGER',7839,TO_DATE('1981-05-01','YYYY-MM-DD'),2850,NULL,30);
INSERT INTO EMP VALUES (7782,'CLARK','MANAGER',7839,TO_DATE('1981-05-09','YYYY-MM-DD'),2450,NULL,10);
INSERT INTO EMP VALUES (7566,'JONES','MANAGER',7839,TO_DATE('1981-04-01','YYYY-MM-DD'),2975,NULL,20);
INSERT INTO EMP VALUES (7654,'MARTIN','SALESMAN',7698,TO_DATE('1981-09-10','YYYY-MM-DD'),1250,1400,30);
INSERT INTO EMP VALUES (7499,'ALLEN','SALESMAN',7698,TO_DATE('1981-02-11','YYYY-MM-DD'),1600,300,30);
INSERT INTO EMP VALUES (7844,'TURNER','SALESMAN',7698,TO_DATE('1981-08-21','YYYY-MM-DD'),1500,0,30);
INSERT INTO EMP VALUES (7900,'JAMES','CLERK',7698,TO_DATE('1981-12-11','YYYY-MM-DD'),950,NULL,30);
INSERT INTO EMP VALUES (7521,'WARD','SALESMAN',7698,TO_DATE('1981-02-23','YYYY-MM-DD'),1250,500,30);
INSERT INTO EMP VALUES (7902,'FORD','ANALYST',7566,TO_DATE('1981-12-11','YYYY-MM-DD'),3000,NULL,20);
INSERT INTO EMP VALUES (7369,'SMITH','CLERK',7902,TO_DATE('1980-12-09','YYYY-MM-DD'),800,NULL,20);
INSERT INTO EMP VALUES (7788,'SCOTT','ANALYST',7566,TO_DATE('1982-12-22','YYYY-MM-DD'),3000,NULL,20);
INSERT INTO EMP VALUES (7876,'ADAMS','CLERK',7788,TO_DATE('1983-01-15','YYYY-MM-DD'),1100,NULL,20);
INSERT INTO EMP VALUES (7934,'MILLER','CLERK',7782,TO_DATE('1982-01-11','YYYY-MM-DD'),1300,NULL,10);

COMMIT;

 

2. Standby DB 생성

 

2-1 Standby DB 디렉토리 생성

cd
mkdir -p /home/oracle/SBDB

(Primary → Standby) 파일 목록 확인 후 복사

2-2. Primary(PROD)에서 파일 경로 확인

-- datafile
SYS@PROD> select file_name from dba_data_files;

-- 필요 시 스크립트 저장
SYS@PROD> save datafile.sql

-- tempfile
SYS@PROD> select file_name from dba_temp_files;
SYS@PROD> save tempfile.sql

-- redo log file
SYS@PROD> select member from v$logfile;
SYS@PROD> save logfile.sql

-- controlfile
SYS@PROD> select name from v$controlfile;
SYS@PROD> save control.sql

 

2-3. Primary(PROD) 종료 후 standby용 디렉토리로 전체 복사

SYS@PROD> shutdown immediate
SYS@PROD> exit
[oracle@ora19c ~]$ cp -rp /u01/app/oracle/oradata/PROD/* /home/oracle/SBDB

 

2-4. 복사 확인(예)

cd /home/oracle/SBDB
ls
# disk1 disk2 disk3 disk4 disk5

cd /home/oracle/SBDB/disk1
ls
# ctrl1.ctl system01.dbf

 


 

3) 아카이브/플래시백 로그 디렉토리 생성

 

3-1. Primary(PROD)

mkdir -p /home/oracle/PROD/arch    # archive log
mkdir -p /home/oracle/PROD/flash   # flashback database log

3-2. Standby(SBDB)

mkdir -p /home/oracle/SBDB/arch
mkdir -p /home/oracle/SBDB/flash

 

Primary → Standby 로 전달되어야 하는 파일

  • 모든 datafile → 전달
  • tempfile → 전달
  • redo log file → 전달
  • standby용 controlfile → 별도 생성(복사본 controlfile을 그대로 쓰지 않음) </aside>

 


 

4) Standby controlfile 생성 및 반영

4-1. PROD를 mount로 올리고 standby controlfile 생성

SQL> startup mount
SQL> alter database create standby controlfile as '$HOME/physical.ctl' reuse;
SQL> exit
cd
ls -l physical.ctl

4-2. 생성한 standby controlfile을 SBDB 경로에 반영

cp $HOME/physical.ctl /home/oracle/SBDB/disk1/ctrl1.ctl
cp $HOME/physical.ctl /home/oracle/SBDB/disk2/ctrl2.ctl
cp $HOME/physical.ctl /home/oracle/SBDB/disk3/ctrl3.ctl

 


5) Listener 정적 등록 및 tnsnames 설정

5-1. 리스너 상태 확인

lsnrctl status

5-2. listener.ora 편집(정적 서비스 등록)

cd $ORACLE_HOME/network/admin
mv listener.ora listener.bak   # 실제로 listener.ora가 없을 수도 있음
vi listener.ora
LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.13.??)(PORT = ????))
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
    )
  )

SID_LIST_LISTENER=
  (SID_LIST =
    (SID_DESC =
      (ORACLE_HOME=/u01/app/oracle/product/19.3.0/dbhome_1)
      (SID_NAME=PROD)
    )
    (SID_DESC =
      (ORACLE_HOME=/u01/app/oracle/product/19.3.0/dbhome_1)
      (SID_NAME=SBDB)
    )
  )

5-3. 리스너 재기동

lsnrctl stop
lsnrctl start

5-4. tnsnames.ora에 PROD/SBDB 추가

cd $ORACLE_HOME/network/admin
vi tnsnames.ora
PROD =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.13.???)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = PROD)
    )
  )

SBDB =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.13.???)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = SBDB)
    )
  )

 


 

6) SBDB password file 확인 및 접속 테스트

cd $ORACLE_HOME/dbs
ls -l orapw*

sqlplus sys/oracle@SBDB as sysdba

7) PROD/SBDB 전환 alias 추가

cd
vi .bash_profile
alias prod='export ORACLE_SID=PROD'
alias sbdb='export ORACLE_SID=SBDB'
source .bash_profile
prod
sbdb

8) Primary(PROD) mount 유지

prod
sqlplus / as sysdba
SQL> shutdown immediate
SQL> startup mount

9) Standby 파라미터 파일(initSBDB.ora) 생성

sbdb
cd $ORACLE_HOME/dbs
vi initSBDB.ora
compatible=19.3.0.0
control_files = (/home/oracle/SBDB/disk1/ctrl1.ctl ,
/home/oracle/SBDB/disk2/ctrl2.ctl ,
/home/oracle/SBDB/disk3/ctrl3.ctl )
db_block_size=8192
db_name=PROD
service_names=SBDB
global_names=true
job_queue_processes=10
open_cursors=500
processes=100
remote_login_passwordfile='EXCLUSIVE'
memory_target=1G
undo_management='AUTO'
undo_tablespace='UNDOTBS1'
db_recovery_file_dest_size=4G
db_recovery_file_dest=/home/oracle/SBDB/flash
db_unique_name=SBDB
standby_file_management=auto
db_file_name_convert='/u01/app/oracle/oradata/PROD','/home/oracle/SBDB'
log_file_name_convert='/u01/app/oracle/oradata/PROD','/home/oracle/SBDB'
log_archive_dest_1='location=/home/oracle/SBDB/arch valid_for=(all_logfiles, all_roles)'
log_archive_dest_2='service=PROD LGWR SYNC AFFIRM valid_for=(online_logfiles, primary_role)'
fal_server=PROD
fal_client=SBDB

 

Standby에서 핵심 파라미터

  • fal_server=PROD: 아카이브 로그를 보내주는(DB)
  • fal_client=SBDB: 아카이브 로그를 받는(DB) </aside>

  • 10) PROD/SBDB 각각 Standby Redo Log 생성
    prod
    sqlplus / as sysdba
    
    alter database drop standby logfile '/u01/app/oracle/oradata/PROD/disk1/standby01.log' ;
    alter database drop standby logfile '/u01/app/oracle/oradata/PROD/disk1/standby02.log' ;
    
    alter database add standby logfile '/u01/app/oracle/oradata/PROD/disk1/standby01.log' size 100m;
    alter database add standby logfile '/u01/app/oracle/oradata/PROD/disk1/standby02.log' size 100m;
    
    10-2. SBDB에서 기동 후 생성
    SQL> startup pfile=$ORACLE_HOME/dbs/initSBDB.ora
    
    SQL> select value
         from v$diag_info
         where name ='Diag Trace';
    
    alter  database drop standby logfile '/home/oracle/SBDB/disk1/standby01.log';
    alter  database drop standby logfile '/home/oracle/SBDB/disk1/standby02.log';
    alter database add standby logfile '/home/oracle/SBDB/disk1/standby01.log' size 100m;
    alter database add standby logfile '/home/oracle/SBDB/disk1/standby02.log' size 100m;
    

    11) PMON 프로세스 확인
  • ps -ef | grep pmon | grep -v grep
    # ora_pmon_PROD
    # ora_pmon_SBDB

  • 12) Standby(SBDB)를 Managed Recovery로 전환
    • SBDB에서 수행
    sbdb
    echo $ORACLE_SID
    # SBDB
    sqlplus / as sysdba
    
    select instance_name from v$instance;
    
    shutdown immediate;
    startup mount;
    
    alter database flashback on;
    
    -- MRP 확인(초기에는 안 뜰 수 있음)
    select process, status from v$managed_standby;
    
    -- Managed Recovery 시작
    recover managed standby database disconnect;
    
    -- MRP 재확인
    select process, status from v$managed_standby;
    
    -- 인스턴스 상태 확인
    select status from v$instance;
    -- STATUS: MOUNTED
    

    13) 동기화/정상 동작 확인
    • PROD
    select name from v$datafile;
    
    • SBDB
    select name from v$datafile;
    
    13-2. Primary(PROD) OPEN
    select instance_name from v$instance;
    
    alter database open;
    
    13-3. PROD에서 테이블스페이스 생성 → SBDB 자동 반영 확인13-4. 양쪽에서 datafile 목록 재확인
    • PROD
    select name from v$datafile;
    
    • SBDB
    select name from v$datafile;
    

    14) VM 종료 순서 (Standby → Primary → VM)14-1) SBDB(Standby) 종료
    lsnrctl stop
    
    14-2) Primary 종료
    lsnrctl stop
    
    14-3) VM 종료
    • Standby(SBDB) → Primary 순서를 지키면, redo apply 도중 Primary를 먼저 내려서 생길 수 있는 아카이브 갭 가능성을 줄일 수 있습니다.
    • Primary를 먼저 내려도 보통 데이터 유실은 없지만, Standby에 FAL 요청 관련 에러 로그가 남을 수 있습니다. </aside>14) VM 종료 순서 (Standby → Primary → VM)14-1) SBDB(Standby) 종료
      lsnrctl stop
      
      14-2) Primary 종료
      lsnrctl stop
      
      14-3) VM 종료
      • Standby(SBDB) → Primary 순서를 지키면, redo apply 도중 Primary를 먼저 내려서 생길 수 있는 아카이브 갭 가능성을 줄일 수 있습니다.
      • Primary를 먼저 내려도 보통 데이터 유실은 없지만, Standby에 FAL 요청 관련 에러 로그가 남을 수 있습니다.