데이터베이스 연구실.log

접속 장애 전환

CTF, TAF, FAN의 차이와 인스턴스 장애 시 서비스 전환 실습, 조회 복구와 미커밋 작업의 한계

RAC접속 장애 전환CTFTAFFANFCFPRECONNECTFAILED_OVERONS

#핵심 요약

CTF는 접속 생성 단계에서 실패한 주소 대신 다른 주소로 재시도하는 기능임

TAF는 이미 연결된 세션의 인스턴스 장애 뒤 재연결과 설정된 범위의 조회 복구임

FAN은 상태 변화의 알림이며 실제 연결 처리와 요청 재시도는 클라이언트 기능에 달려 있음

세션이 넘어갔는지는 GV$SESSION의 FAILOVER_TYPE, FAILOVER_METHOD, FAILED_OVER로 확인함

#개념과 동작 원리

설정, 기능 담당 범위
LOAD_BALANCE 주소 선택과 분산
FAILOVER 접속 실패 시 다른 주소로 재시도
FAILOVER_MODE 연결된 세션의 TAF 방식 지정
TAF SESSION 세션 재연결이며 진행 중 SELECT의 결과 수신 재개는 제공하지 않음
TAF SELECT 재연결 후 조회를 재실행해 이미 받은 행을 제외한 Fetch 복구 가능
BASIC 장애 후 대체 연결 생성
PRECONNECT 장애 전에 백업 연결을 확보하므로 추가 연결 자원 필요
FAN, ONS 노드, 인스턴스, 서비스의 UP/DOWN 상태 이벤트 전달
FCF FAN을 사용하는 연결 풀의 장애 연결 정리와 관리
구분 적용 시점
CTF 세션 생성 전 최초 접속 단계
TAF 이미 연결된 세션의 인스턴스 장애 이후

TAF SELECT는 지원 클라이언트와 설정, 조회 복구 조건이 충족돼야 하며 기존 인스턴스 메모리와 세션 전체를 복사하는 기능은 아님

FAILOVER의 기본값은 ON이므로 tnsnames.ora에서 생략했다고 CTF가 꺼졌다고 판단하지 않음
실습 과제에는 FAILOVER = on을 지운 뒤 접속을 비교하는 항목이 있었음

노드 장애 때 VIP가 다른 노드로 옮겨 가거나 접속 실패를 빨리 돌려줘, 긴 TCP timeout 대기 없이 다음 주소로 넘어가게 도와줌

FAN은 SQL 실행 실패나 TCP timeout으로 장애를 알아차리는 지연을 줄이고, ONS가 Clusterware와 DB의 이벤트를 지원 클라이언트와 미들웨어에 전달함

구분 TAF FCF
적용 대상 개별 세션 연결 풀 전체
감지 수업 자료는 TCP timeout 뒤 감지로 정리 ONS 이벤트
중간 계층 제한적 UCP, JDBC, ODP.NET

수업 자료의 "TAF는 TCP timeout 뒤 감지"는 모든 지원 클라이언트의 감지 동작을 단정하는 기준으로 쓰지 않음
서비스의 -failovertype은 SESSION, SELECT가 TAF, TRANSACTION이 Application Continuity(AC), AUTO가 Transparent Application Continuity(TAC)에 해당함

#PDB 서비스의 장애 전환

PDB 연결 서비스를 한 인스턴스에 Preferred, 다른 인스턴스에 Available로 두면, 인스턴스 장애 때 Clusterware가 Available 인스턴스에서 서비스를 기동하고 연결된 PDB를 열어 접속을 받음
수업 자료의 흐름: 인스턴스 장애 감지 → Available 인스턴스의 서비스 기동과 PDB OPEN → FAN 상태 통지 → TAF 세션 재연결 실제 DOWN/UP 이벤트와 클라이언트 반응 시점은 구성과 장애 상황에 따라 달라짐 서비스 속성으로 TAF 정책을 두면 클라이언트마다 같은 FAILOVER_MODE를 반복해 적지 않아도 됨

#필수 명령어 또는 SQL

#클라이언트 TAF 별칭

tnsnames.ora (클라이언트)객체 또는 설정을 변경함
<TAF_ALIAS> =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (LOAD_BALANCE = on)
      (FAILOVER = on)
      (ADDRESS = (PROTOCOL = TCP)(HOST = <VIP_1>)(PORT = 1521))
      (ADDRESS = (PROTOCOL = TCP)(HOST = <VIP_2>)(PORT = 1521)))
    (CONNECT_DATA =
      (SERVICE_NAME = <SERVICE_NAME>)
      (FAILOVER_MODE = (TYPE = SELECT)(METHOD = BASIC))))

<NO_TAF_ALIAS> =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (LOAD_BALANCE = on)
      (FAILOVER = on)
      (ADDRESS = (PROTOCOL = TCP)(HOST = <VIP_1>)(PORT = 1521))
      (ADDRESS = (PROTOCOL = TCP)(HOST = <VIP_2>)(PORT = 1521)))
    (CONNECT_DATA = (SERVICE_NAME = <SERVICE_NAME>)))

결과 해석:

실습 기록:

  1. CTF: 접속하는 인스턴스가 번갈아 나오는 것을 본 뒤 <INSTANCE1>을 SHUTDOWN IMMEDIATE로 내리고 새로 접속하자 <INSTANCE2>로 붙었음
  2. TAF 없는 별칭: <INSTANCE1>에 붙은 세션은 <INSTANCE1>을 SHUTDOWN ABORT한 뒤 다음 조회에서 ORA-03113: end-of-file on communication channel로 끊겼고, 다시 접속해야 <INSTANCE2>로 붙었음
  3. TYPE=SELECT: emp를 INSERT INTO emp SELECT * FROM emp 반복으로 수만 건으로 늘리고 조회 결과를 받는 도중 <INSTANCE1>을 SHUTDOWN ABORT하자, 조회가 잠시 멈췄다가 <INSTANCE2>로 넘어가 이어졌음

#PRECONNECT와 백업 연결

tnsnames.ora (클라이언트)객체 또는 설정을 변경함
<PRIMARY_ALIAS> =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = <VIP_1>)(PORT = 1521))
    (CONNECT_DATA =
      (SERVICE_NAME = <SERVICE_NAME>)
      (INSTANCE_NAME = <INSTANCE1>)
      (FAILOVER_MODE =
        (BACKUP = <BACKUP_ALIAS>)
        (TYPE = SELECT)(METHOD = PRECONNECT)
        (RETRIES = 30)(DELAY = 5))))

<BACKUP_ALIAS> =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = <VIP_2>)(PORT = 1521))
    (CONNECT_DATA = (SERVICE_NAME = <SERVICE_NAME>)(INSTANCE_NAME = <INSTANCE2>)))
SQL*Plus (SYSDBA, 별도 창)조회만 함
SELECT inst_id, sid, username, failover_type, failover_method, failed_over
  FROM gv$session
 WHERE username = '<USERNAME>';

결과 해석:

BACKUP이 없으면 미리 만들 백업 연결의 대상을 정할 수 없고, LOAD_BALANCE = on이면 주 연결이 1번 인스턴스로 고정되지 않을 수 있어 실습에서는 주 별칭과 백업 별칭을 인스턴스별로 따로 뒀음

실습 기록: PRECONNECT 별칭으로 접속하자 2번 노드의 서버 프로세스가 22개에서 23개로 늘어 백업 연결이 미리 잡힌 것을 확인했음
확인 기준은 inst_id 1과 2에 같은 사용자 세션이 있고 FAILOVER_METHOD = PRECONNECT인 것, <INSTANCE1> SHUTDOWN ABORT 뒤 inst_id 2 세션의 FAILED_OVER = YES임

서버측 TAF의 srvctl -failovermethod는 NONE, BASIC만 받으며 PRECONNECT는 클라이언트 tnsnames.ora에서만 지정함

#서비스 속성으로 서버측 TAF

oracle 계정 셸 (1번 노드)객체 또는 설정을 변경함
srvctl add service -db <DB_NAME> -service <SERVICE_NAME> \
  -preferred <INSTANCE1> -available <INSTANCE2> \
  -failovertype SELECT -failovermethod BASIC \
  -failoverretry 30 -failoverdelay 5 -notification TRUE
srvctl start service  -db <DB_NAME> -service <SERVICE_NAME>
srvctl config service -db <DB_NAME> -service <SERVICE_NAME> | grep -i -E 'failover|notification'
srvctl status service -db <DB_NAME> -service <SERVICE_NAME>

결과 해석:

기본 서비스(DB 이름과 같은 서비스)는 srvctl로 바꿀 수 없어 업무용 서비스를 따로 만듦

클라이언트 별칭은 SERVICE_NAME만 적고 FAILOVER_MODE를 생략함
서비스의 TAF 속성이 클라이언트 FAILOVER_MODE보다 우선한다고 수업 자료는 정리함

확인 기준: GV$SESSION에서 FAILOVER_TYPE = SELECT, FAILOVER_METHOD = BASIC, 장애 뒤 FAILED_OVER = YES, srvctl status service에서 서비스가 <INSTANCE2>로 옮겨 감

#PDB 서비스 장애 전환 실습

oracle 계정 셸 (1번 노드, 2번 노드)인스턴스 또는 서비스 중단이 필요함
srvctl modify service -db <DB_NAME> -service <SERVICE_NAME> \
  -failovertype SELECT -failovermethod BASIC \
  -failoverretry 30 -failoverdelay 5 -notification TRUE
srvctl config scan
lsnrctl services | grep -i <SERVICE_NAME>

# 조회 결과를 한 화면씩 넘기는 도중 다른 노드에서
srvctl stop instance -db <DB_NAME> -instance <INSTANCE1> -stopoption abort
srvctl status service -db <DB_NAME> -service <SERVICE_NAME>

# 확인 뒤 원래대로
srvctl start instance -db <DB_NAME> -instance <INSTANCE1>
srvctl relocate service -db <DB_NAME> -service <SERVICE_NAME> -oldinst <INSTANCE2> -newinst <INSTANCE1>
SQL*Plus (2번 노드 SYSDBA)조회만 함
SELECT inst_id, open_mode FROM gv$pdbs WHERE name = '<PDB_NAME>';

SELECT inst_id, username, service_name, failover_type, failover_method, failed_over
  FROM gv$session
 WHERE username = '<USERNAME>';

결과 해석:

리스너에 등록된 실제 서비스 이름에 도메인이 붙었는지 lsnrctl services로 먼저 확인하고, tnsnames.ora 별칭은 SCAN 주소와 그 서비스 이름으로 1번 노드, 2번 노드 모두에 둠

실습 기록: 접속 세션은 SYS_CONTEXT('userenv', 'instance_name')이 <INSTANCE1>이었고, SET PAUSE ON으로 dba_objects를 넘기는 도중 <INSTANCE1>을 abort하자 서비스가 <INSTANCE2>로 옮겨 갔으며 Enter로 조회가 이어진 뒤 <INSTANCE2>, FAILED_OVER = YES로 나왔음

#FAN, FCF용 서비스와 ONS 점검

oracle 계정 셸객체 또는 설정을 변경함
srvctl add service -db <DB_NAME> -service <SERVICE_NAME> \
  -preferred <INSTANCE1>,<INSTANCE2> \
  -failovertype AUTO -failovermethod BASIC \
  -failoverretry 180 -failoverdelay 5 \
  -commit_outcome TRUE -replay_init_time 600 -notification TRUE

srvctl status ons
srvctl config ons
crsctl status resource -t
SQL*Plus (SYSDBA)조회만 함
SELECT name, aq_ha_notifications, failover_method, failover_type,
       failover_retries, failover_delay, clb_goal
  FROM dba_services
 WHERE LOWER(name) = '<SERVICE_NAME>';

결과 해석:

-commit_outcome TRUE는 커밋 결과를 추적해 중복 커밋을 막고, -replay_init_time 600은 장애 뒤 600초 안의 재실행을 허용한다고 수업 자료는 설명함

수업 자료에는 DBMS_SERVICE.MODIFY_SERVICE로 aq_ha_notifications => TRUE와 FAILOVER_TYPE_SESSION, FAILOVER_TYPE_SELECT를 바꾸는 예도 있음
"TRANSACTION"이라는 주석과 실제 값 FAILOVER_TYPE_SELECT가 맞지 않고, Clusterware가 관리하는 서비스는 srvctl 정의가 기준이라 DBMS_SERVICE 변경이 재기동 때 덮어써질 수 있음

19c 클라이언트는 SCAN 주소 하나만 적어도 SCAN 이름이 가리키는 여러 IP로 분산된다고 수업 자료는 설명함

#확인 문제: 노드 점검 때 TAF 조회 세션이 넘어가는지 미리 확인

상황: 2번 노드 서버 점검으로 <INSTANCE2>를 강제로 내려야 하고, 조회 사용자들은 TAF 별칭으로 접속해 있음
다시 로그인하지 않고 계속 조회되는지, 실제로 넘어간 세션인지 숫자로 보이고 점검 뒤 <INSTANCE2>를 다시 올려야 함

실습에서는 TAF 별칭으로 접속을 반복해 <INSTANCE2>에 붙은 세션을 하나 만들고 emp를 조회한 채 창을 열어 둠

SQL*Plus (SYSDBA, 1번 노드)조회만 함
SELECT inst_id, username, failover_type, failover_method, failed_over
  FROM gv$session
 WHERE username = '<SCHEMA>';
OS (1번 노드, oracle)인스턴스 또는 서비스 중단이 필요함
srvctl stop instance -db <DB_NAME> -instance <INSTANCE2> -stopoption abort
srvctl status database -db <DB_NAME>
SQL*Plus (열어 둔 TAF 세션)조회만 함
SELECT instance_name FROM v$instance;
SELECT empno, ename, sal FROM emp WHERE deptno = 20;
OS (1번 노드, oracle)객체 또는 설정을 변경함
srvctl start instance -db <DB_NAME> -instance <INSTANCE2>
srvctl status database -db <DB_NAME>

결과 해석:

예상값: 장애 전 INST_ID 2, SELECT, BASIC, NO, 장애 뒤 같은 조회가 다시 로그인 없이 되고 INST_ID 1, FAILED_OVER = YES

-stopoption abort는 SHUTDOWN ABORT에 해당함

FAILED_OVER = YES 세션과 장애 뒤 새로 접속한 세션(NO)을 구분함

TYPE=SELECT는 조회만 이어 주며, 장애 순간의 미커밋 DML은 롤백되어 애플리케이션이 다시 실행해야 함
실행 결과 확인 불가

#사용 조건과 주의사항

조회 Fetch 복구와 미커밋 UPDATE 복구는 다르며 TAF는 미커밋 DML을 자동 재실행하지 않음
인스턴스 장애 복구는 미커밋 트랜잭션을 롤백하며, 재실행은 AC, TAC의 영역임

SQL*Plus 세션 하나가 다른 인스턴스로 다시 붙은 결과만으로 연결 풀의 FCF 동작을 입증할 수 없음

notification 설정만으로 모든 클라이언트의 자동 복구가 보장되지 않음

SHUTDOWN ABORT, srvctl stop instance -stopoption abort는 해당 인스턴스의 모든 세션을 끊으므로 운영 환경에서 시험하지 않음

SEO_HKabsumveritas@gmail.comBuilt with Claude Code & Codex

마지막 갱신 개인 학습 기록이며 운영 환경 적용 전 공식 문서 확인 필요

두 글자 이상 입력, 위아래 화살표로 이동하고 Enter로 열기