[개발 환경]
- 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
10-2. SBDB에서 기동 후 생성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;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 sysdbaselect 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
13-2. Primary(PROD) OPENselect name from v$datafile;
13-3. PROD에서 테이블스페이스 생성 → SBDB 자동 반영 확인13-4. 양쪽에서 datafile 목록 재확인select instance_name from v$instance; alter database open;- PROD
select name from v$datafile;- SBDB
select name from v$datafile;
14) VM 종료 순서 (Standby → Primary → VM)14-1) SBDB(Standby) 종료
14-2) Primary 종료lsnrctl stop
14-3) VM 종료lsnrctl stop- Standby(SBDB) → Primary 순서를 지키면, redo apply 도중 Primary를 먼저 내려서 생길 수 있는 아카이브 갭 가능성을 줄일 수 있습니다.
- Primary를 먼저 내려도 보통 데이터 유실은 없지만, Standby에 FAL 요청 관련 에러 로그가 남을 수 있습니다. </aside>14) VM 종료 순서 (Standby → Primary → VM)14-1) SBDB(Standby) 종료
14-2) Primary 종료lsnrctl stop
14-3) VM 종료lsnrctl stop- Standby(SBDB) → Primary 순서를 지키면, redo apply 도중 Primary를 먼저 내려서 생길 수 있는 아카이브 갭 가능성을 줄일 수 있습니다.
- Primary를 먼저 내려도 보통 데이터 유실은 없지만, Standby에 FAL 요청 관련 에러 로그가 남을 수 있습니다.