리커버리 끝났는데 XID가 왜 안 사라지죠? – GoldenGate 실전 삽질기

GoldenGate XID — 리커버리 후 남은 단서 주제를 표현한 개념 그림
리커버리 끝났는데 XID가 왜 안 사라지죠? - GoldenGate 실전 삽질기
🔥 후속편
리커버리 끝났는데
XID가 왜 안 사라지죠?

Oracle GoldenGate 체크포인트 지연 후속 사례
당시 기록: 전체 Extract 정상화까지 3일

복구 완료 뒤에도 남은 XID

관측한 상황: 복구 완료 상태가 표시된 뒤에도 SHOWTRANS 결과에 같은 XID가 남아 있었습니다. 복구 완료와 열린 트랜잭션 목록이 비는 것은 같은 조건이 아닙니다.
"아니, Recovery complete라면서요? 왜 아직도 XID 14.15.4795600이 남아있죠? 😱"

당시 기록에 남은 순서는 다음과 같습니다:

  • Extract를 순차적으로 재기동
  • 모든 Extract에서 "Recovery complete: Processing data" 상태 확인
  • 일부 Extract(예: 01CD086E)의 SHOWTRANS에 같은 XID가 계속 표시
  • 다음 날 새로운 XID(14.4.4794298)도 관측

당시 작업 기록

당시 기록에는 38GB 인덱스 두 개의 리빌드 이후 전체 Extract가 따라잡는 데 3일이 걸렸다고 남아 있습니다. 이 기간은 해당 사례의 결과이며 보편적인 복구 시간이나 리빌드의 단독 원인을 입증하지는 않습니다. 대규모 작업 전에는 복제 중단의 영향과 로그 보존·재개 조건을 함께 검토해야 합니다.

지연 지표와 복구 위치의 구분

GETLAG는 마지막 레코드의 소스 시각과 Extract 처리 시각 차이입니다. Checkpoint Lag는 체크포인트 기준의 지연 지표이며 재시작 위치 자체는 아닙니다. GETLAG가 낮아도 타깃 반영이 정상이라고 단정할 수 없고, 복구에 필요한 위치는 체크포인트·redo 정보로 별도 확인해야 합니다.

잔존 XID를 해석할 때 확인할 항목

다음은 당시 조사한 가능성과 확인 항목입니다. 현재 설치 버전이나 해당 사건의 내부 상태를 새로 검증한 결과는 아닙니다:

확인 1: 활성 트랜잭션과 Extract 추적 상태

활성 트랜잭션 조회에 XID가 없다는 사실만으로 커밋 완료나 Extract 캐시의 잔존 상태가 입증되지는 않습니다. 조회 인스턴스·컨테이너·시각과 XID 조건을 맞추고, Extract 보고서와 복구 위치를 대조해야 합니다. DB가 조용하다는 이유만으로 새 트랜잭션을 발생시키거나 재기동하지 마세요.

확인 2: 새 XID와 후속 작업의 관계

리빌드 뒤 새 XID가 나타나면 해당 시간대의 작업과 redo 기록을 대조합니다. 내부 SQL 활동이나 별도 작업도 조사 대상이지만, 새 XID라는 이유만으로 앞선 리빌드의 후속 트랜잭션이라고 단정할 수는 없습니다.

확인 3: Extract 방식과 상태 표시 범위

당시에는 다음처럼 위치가 0으로 표시되는 결과도 관측했습니다:

  • Redo thread #: 0
  • Sequence #: 0
  • RBA: 0
  • 타임스탬프가 진행하지 않는 것으로 관측

이 표시만으로 Integrated 모드의 정상 상태나 장애를 판정하지 마세요. 실제 Extract 방식과 설치 버전을 확인하고 INFO EXTRACT xxx, DETAIL의 상세 위치를 보고서·DB 캡처 상태와 대조해야 합니다.

진행 여부를 확인하고 조치를 결정하는 순서

당시 사용한 세 가지 확인 항목 (5–10분은 예시 간격)

체크 1: STATUS 확인 SEND EXTRACT 그룹명, STATUS

지원되는 위치와 시각이 같은 기준에서 진행하는지 비교합니다. 0 표시만으로 정지를 판단하지 않습니다.

체크 2: SHOWTRANS 확인 SEND EXTRACT 그룹명, SHOWTRANS DURATION 240 MIN

XID와 유지 시간을 기록합니다. DURATION 240 MIN은 240분 초과 필터이며, 15–20분 유지 자체는 장애나 재기동 기준이 아닙니다.

체크 3: STATS 확인 STATS EXTRACT 그룹명 LATEST

같은 그룹·테이블·집계 구간의 처리 수를 비교합니다. 통계 증가와 타깃 적용 정상화는 별도 판단이며, 소스에 변경이 없으면 처리 수도 늘지 않을 수 있습니다.

상황별 대응법

관찰을 지속할 수 있는지 확인

✓ DB 활동 거의 없음
✓ 에러 메시지 없음
✓ I/O 병목 없음
✓ 아카이브 충분함
→ 소스 부하와 타깃 반영, 허용 지연을 대조해 관찰 지속 여부를 결정합니다. 위 단서만으로 정상이나 무기한 대기를 확정하지 마세요.

재기동을 검토하기 전 추가 확인

✓ 같은 XID가 15–30분 유지됨: 예시 관찰 구간이며 장애 확정 기준은 아님
✓ ggserr.log에 에러 없음
✓ 아카이브도 충분함
→ 실제 정체와 복구 조건을 확인한 뒤 승인된 절차에서 해당 Extract의 재기동을 검토합니다. FORCESTOP은 즉시 중지하므로 정상 중지 가능 여부와 영향을 먼저 확인하세요. 코드의 10–20초는 안전을 보장하는 대기 시간이 아닙니다:

당시 재기동 예시 — 그대로 실행 금지
GGSCI> SEND EXTRACT 그룹명, FORCESTOP
-- 꼭! 10-20초 기다리세요
GGSCI> START EXTRACT 그룹명
동시 복구 범위의 판단: 3개는 이 사례에서 선택한 동시 복구 수이며 제품의 보편적인 한계가 아닙니다. CPU·메모리·I/O와 캡처 부하를 측정하고, 재기동이 승인된 경우 한 프로세스씩 상태와 영향을 확인하세요.

LogMiner 분석의 적용 조건과 결과 해석

LogMiner는 해당 XID의 redo 기록을 대조하는 수단입니다. 아래는 당시 예제이므로 그대로 실행하지 마세요. 권한, DB 버전·컨테이너, 사전(dictionary)과 로그 범위·연속성, 실제 경로를 먼저 확인해야 합니다. 특히 3단계의 xid_usn/xid_slot/xid_sqn 표기는 Oracle 19c 공식 뷰의 XIDUSN/XIDSLT/XIDSQN과 다르므로 별도 코드 수정 전에는 실행 가능한 예제로 간주하면 안 됩니다.

1단계: 아카이브 확인
-- 해당 구간 아카이브가 있는지 먼저 확인
SELECT sequence#, name, first_time, next_time
FROM v$archived_log
WHERE thread# = 1 
  AND sequence# BETWEEN 74849 AND 74870
ORDER BY sequence#;
2단계: LogMiner 시작
BEGIN
  -- 첫 번째 아카이브 추가
  DBMS_LOGMNR.ADD_LOGFILE(
    LOGFILENAME => 'E:\ORACLE\...\첫번째아카이브.ARC', 
    OPTIONS => DBMS_LOGMNR.NEW
  );
  
  -- 나머지 아카이브들 추가
  DBMS_LOGMNR.ADD_LOGFILE(
    LOGFILENAME => 'E:\ORACLE\...\두번째아카이브.ARC', 
    OPTIONS => DBMS_LOGMNR.ADDFILE
  );
  
  -- LogMiner 시작!
  DBMS_LOGMNR.START_LOGMNR(
    OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG
  );
END;
/
3단계: XID 기록 대조 — 열 이름 별도 확인
-- XID로 직접 찾기 (예: 14.15.4795600)
SELECT timestamp, scn, operation, 
       seg_owner, seg_name, sql_redo
FROM   v$logmnr_contents
WHERE  xid_usn  = 14
  AND  xid_slot = 15
  AND  xid_sqn  = 4795600
ORDER BY scn;

결과 해석법

  • COMMIT이 보이면: 같은 XID·DB·redo 범위의 커밋 기록인지 확인합니다. 이것만으로 Extract 내부 상태나 타깃 반영이 입증되거나 재기동이 허용되는 것은 아닙니다.
  • COMMIT이 안 보이면: 미완료로 단정하지 마세요. 분석 범위 밖의 커밋, 누락 로그, 필터와 컨테이너 조건을 확인하고 활성 트랜잭션·작업 기록을 대조합니다.

당시 대응에서 얻은 운영상 주의점

1. 재기동의 복구 비용 확인

재기동은 복구 작업과 부하를 추가할 수 있습니다. 장기 트랜잭션, 필요한 redo와 복구 위치를 확인한 뒤 결정하고, 진행 중인 복구를 반복해서 중단하지 마세요.

2. 동시 복구 수는 환경별로 결정

🎪 실제 경험

당시 기록에는 다섯 Extract를 동시에 복구할 때 I/O 경쟁과 LogMiner 부하를 겪었고, 세 개씩 나눠 진행했다고 남아 있습니다. 이 경험을 모든 서버의 안전 동시 실행 수나 성능 보장으로 일반화하지 마세요.

3. Windows I/O와 보안 검사 영향 분리

먼저 저장장치와 프로세스별 I/O를 측정해 보안 검사가 병목인지 확인합니다. 백신 제외는 보호 범위를 줄이므로 일괄 권장하지 않습니다. 필요성이 입증된 경우에도 보안 담당자의 승인과 최소 범위 검토가 필요합니다. 아래 카운터는 관찰 예시입니다:

PowerShell I/O 체크
# PowerShell에서 실행
Get-Counter '\PhysicalDisk(_Total)\Avg. Disk sec/Transfer',
            '\PhysicalDisk(_Total)\Disk Reads/sec',
            '\PhysicalDisk(_Total)\Current Disk Queue Length' `
            -SampleInterval 1 -MaxSamples 60

Avg. Disk sec/Transfer의 단위는 초입니다. 낮은 평균이나 _Total 집계만으로 I/O 문제가 없다고 판정하지 말고, 디스크별 지연·읽기/쓰기·부하 지속 시간과 Extract 처리 추이를 함께 비교하세요.

4. Bounded Recovery 실패와 로그 보존

Bounded Recovery가 실패하면 보통 일반 복구로 전환하지만 모든 손상에서 자동 복구가 보장되지는 않습니다. 오류와 필요한 redo를 확인하고, 복구 파일 삭제나 BR 옵션 변경은 임의로 수행하지 마세요.

📝 인덱스 리빌드 전 체크리스트

작업 전에 확인할 조건

□
업무·배치 부하와 허용 복제 지연을 고려해 작업 일정 선정
□
병렬도는 자원 부하와 작업 시간을 측정해 결정 (4–8은 당시 예시)
□
유효한 FORCE LOGGING의 우선순위와 DB·테이블스페이스 로깅 정책 확인
□
조회 범위를 맞춰 활성·장기 트랜잭션과 Extract 추적 상태 대조
□
복구에 필요한 로그의 연속성·가독성과 보존 공간 확인
□
복제 중단 영향과 로그 보존·복구·재개 절차를 검토한 뒤 정지 여부 결정

정리: 복구 완료와 정상화는 별도로 확인

Recovery complete인데 XID가 남아있다?
후속 작업·활성 트랜잭션과 Extract 추적 상태를 대조하고
조회 범위, 실제 처리 진행과 타깃 반영을 확인하세요.

기다림이나 재기동 중 하나를 증상만으로 선택하지 마세요. 허용 지연과 복구 조건을 근거로 대응을 결정해야 합니다.
"38GB 인덱스 리빌드 → Extract 전체 정상화까지 3일... 이게 현실이에요 😅"

꼭 기억할 것들

  • STATUS·SHOWTRANS·STATS의 측정 범위를 구분하고 타깃 상태까지 대조
  • LogMiner 분석 범위와 한계를 확인한 뒤 기록을 해석
  • 필요한 redo 위치에 맞춰 로그 보존 정책과 복구 가능성 확인
  • 동시 복구 부하를 측정하고 승인된 범위에서 순차 재기동
  • 관찰 지속 여부도 진행 상태와 허용 지연을 근거로 결정

📌 마지막 팁

1편의 지표 구분과 로그·복구 조건 확인을 함께 적용하세요. 이 사례의 소요 시간이나 재기동 경험을 현재 환경의 해결 보장으로 해석해서는 안 됩니다.

📚 자주 쓰는 명령어 모음

당시 명령 예시 — 버전·복구 조건 확인 후 사용
-- 상태 확인 3종 세트
SEND EXTRACT 그룹명, STATUS
SEND EXTRACT 그룹명, SHOWTRANS DURATION 240 MIN
STATS EXTRACT 그룹명 LATEST

-- 지연 확인
SEND EXTRACT 그룹명, GETLAG
LAG EXTRACT 그룹명

-- 조심스러운 재시작
SEND EXTRACT 그룹명, FORCESTOP
-- 꼭 기다리세요!
START EXTRACT 그룹명

📥 실전 플레이북 다운로드

당시 LogMiner 예제와 체크리스트입니다. 원본 코드는 보존했으므로 열 이름·경로·버전과 복구 조건을 검토하기 전에는 실행하지 마세요.

"3일간의 리커버리 대장정을 통해 깨달은 진리:
때로는 아무것도 안 하는 게 최선의 해결책이다."


- 27년차 오라클 전문가의 체념... 아니, 깨달음 😌

위로 스크롤