Skip to content
튜닝 연습Lock과 동시성 제어
LOCK-037

아무도 고치지 않은 테이블을 읽는 아침 추출이 ORA-01555로 죽는다

실전SELECT한빛유통532 / 700

상황 ​

한빛유통의 DW 추출은 매일 06:00에 T_ORD_BIG 100만 행을 파일로 내린다. 네트워크와 파일 쓰기 때문에 약 9분 걸린다. 이번 주 월요일과 목요일에 추출이 06:07 무렵 ORA-01555로 죽었다. 조민우가 확인한 사실은 이렇다. "06시 이후로 T_ORD_BIG을 고친 세션은 하나도 없어요. 다른 사람이 언두를 덮을 일이 없는데요." 두 날 모두 05:20에 「주문 구간 재계산」 배치가 돌았고, 06:00에는 아침 특가가 열렸다.

테이블과 인덱스 ​

  • T_ORD_BIG 대용량 주문: 1,000,000행 · 5,826블록 · 인덱스 없음 · 이 문제에서는 주문 구간 ORD_GRP(H, M, L)를 더했다
  • 「주문 구간 재계산」 배치(월요일과 목요일 05:20): 최근 1년 주문 약 33만 행의 ORD_GRP를 한 문장으로 다시 계산한다. 5,790블록을 고치고 05:39에 한 번 COMMIT한다.
  • 버퍼 캐시 256MB(32,768블록) · 언두 테이블스페이스 100MB 고정(AUTOEXTEND OFF) · undo_retention 900
  • 06:00에 아침 특가가 열리면 주문과 결제, 적립 트랜잭션이 T_ORD, T_ORD_DET, M_CUS를 고치며 10분에 4만 번 넘게 COMMIT한다. T_ORD_BIG은 건드리지 않는다.
  • 배치가 없는 화요일, 수요일, 금요일에는 추출이 늘 성공한다.

원본 SQL ​

sql
-- 05:20 「주문 구간 재계산」 배치 (월 · 목)
UPDATE T_ORD_BIG
   SET ORD_GRP = CASE WHEN ORD_AMT >= 100000 THEN 'H'
                      WHEN ORD_AMT >= 30000  THEN 'M' ELSE 'L' END
 WHERE ORD_DT >= ADD_MONTHS(TRUNC(SYSDATE), -12);
COMMIT;

-- 06:00 DW 추출 (커서 하나로 100만 행을 읽어 파일로 쓴다 · 약 9분)
SELECT ORD_SEQ, CUS_ID, ORD_DT, ORD_ST, ORD_AMT, ORD_GRP
  FROM T_ORD_BIG;

실행계획 학습용 예시 · 지연 클린아웃의 통계 모양은 교재 13화 실측 ​

xplan
[시간표 — 목요일]
05:20:02   재계산 배치 UPDATE 시작 (약 33만 행 · 5,790블록)
05:39:47   COMMIT — 커밋하면서 ITL 을 닫은(커밋 SCN 을 적은) 블록은 그때 캐시에 남아 있던 일부뿐
06:00:00   아침 특가 오픈 — T_ORD · T_ORD_DET · M_CUS 트랜잭션 10분에 44,870번 COMMIT
06:00:05   DW 추출 OPEN (읽기 시점 고정) · FULL 로 흘려 읽으며 파일로 쓴다
06:07:31   712,000행째 FETCH → ORA-01555: snapshot too old: rollback segment number 4 with name "_SYSSMU4_1180424173$" too small

[추출 세션 — V$SESSTAT · OPEN 뒤 증가분 (06:07:30)]
  consistent gets                                                  9,214
  redo size                                                      161,240   ← 읽기만 하는데 redo 를 쓴다
  cleanouts only - consistent read gets                            1,786
  immediate (CR) block cleanout applications                       1,786
  transaction tables consistent reads - undo records applied      24,610
  transaction tables consistent read rollbacks                       118
  data blocks consistent reads - undo records applied                  0   ← T_ORD_BIG 데이터를 되돌린 일은 없다

[V$UNDOSTAT — 06:00 ~ 06:10]
  UNDOBLKS 11,920 · TXNCOUNT 44,870 · MAXQUERYLEN 446 · TUNED_UNDORETENTION 300 · UNXPSTEALCNT 214 · SSOLDERRCNT 1

[화요일 — 배치가 없는 날 · 같은 추출]
  redo size 0 · cleanouts only - consistent read gets 0 · transaction tables consistent reads - undo records applied 0 · 9분 12초 성공

문제 ​

  1. 06:00 이후 아무도 고치지 않은 T_ORD_BIG을 읽는데 ORA-01555가 난 이유를 세션 통계와 V$UNDOSTAT, 배치가 있는 날만 죽는다는 사실로 설명하시오.
  2. 대안을 셋 이상 비교하고 하나를 골라 SQL로 작성하시오. 대안마다 대가와, 고른 대안이 정말 효과가 있는지 확인하는 방법을 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자