테마
본사 레거시 유통에서 3월 1일 적용 판매가(CF05) 일부가 잘못 등록돼 있어 정정했고, 이어서 판매상품(CF11)의 판매 단가를 정정 단가로 다시 맞추는 배치를 돌렸다. 평소라면 새벽에 돌릴 일을 매장 정산 마감 때문에 오전 10:00에 돌렸다. 매장 POS는 영업 중이었다.
10:03:52에 배치가 ORA-01555로 죽었다. 본사 전산 담당자가 물었다. "언두가 모자라지 않게 1,000건마다 커밋했는데요. 그냥 다시 돌리면 되나요?"
CF11 판매상품: 1,096,708행 · 8,204블록 · CF11_PK (SLE_NO, ITM_NO) · 2023-03-01 이후 판매분 약 46만 행 · 영업 중에는 POS가 반품이나 수량 정정으로 계속 UPDATE하고 COMMIT한다CF10 판매: 500,000행 · 4,583블록 · CF10_PK (SLE_NO) · SLE_DT VARCHAR2(8)CF05 상품가격: 157행 · 5블록 · PK (ITM_NO, UPRC_KN_CD, APL_DT) · 정정한 3월 1일 판매가(UPRC_KN_CD = '01')는 109개 상품 모두 있다 · 그 뒤 판매가 변경은 없다undo_retention 900DECLARE
v_uprc CF05.ITM_UPRC%TYPE;
n PLS_INTEGER := 0;
BEGIN
FOR r IN (SELECT d.ROWID AS rid, d.ITM_NO
FROM CF10 h, CF11 d
WHERE d.SLE_NO = h.SLE_NO
AND h.SLE_DT >= '20230301') LOOP
SELECT ITM_UPRC INTO v_uprc
FROM CF05
WHERE ITM_NO = r.ITM_NO AND UPRC_KN_CD = '01' AND APL_DT = '20230301';
UPDATE CF11 SET SLE_UPRC = v_uprc WHERE ROWID = r.rid;
n := n + 1;
IF MOD(n, 1000) = 0 THEN COMMIT; END IF; -- 언두가 모자라지 않게 (본사 전산 규칙)
END LOOP;
COMMIT;
END;
[시간표 — 오전 · 매장 영업 중]
시각 세션 A — 단가 정정 배치 (SID 131) 세션 B · C — 매장 POS (SID 47 · 62)
10:00:00 OPEN 커서 — 읽기 시점(SCN)이 여기서 고정된다
CF10 ⋈ CF11 을 판매번호 순으로 흘려 읽는다 (정렬 없음)
10:00:01 ~ FETCH → 단가 조회 → UPDATE CF11 → 1,000 건마다 COMMIT 반품 · 수량 정정 UPDATE CF11 → COMMIT (분당 수십 건)
(COMMIT 마다 그 1,000 건의 언두가 '덮어써도 되는' 칸이 된다)
10:02 ~ 커서가 OPEN 뒤에 바뀐 블록에 닿을 때마다 언두로 10:00 의 과거 사본(CR)을 만들어 읽는다
10:03:52 FETCH 287,001 번째 → ORA-01555: snapshot too old: rollback segment number 7 with name "_SYSSMU7_2180427191$" too small
→ 배치 종료. 287,000 건은 이미 COMMIT · 나머지 약 17만 건은 옛 단가 그대로
(B · C 는 기다리지 않는다 — 블로킹이 아니라 '과거가 사라진' 장애다)
[알림 로그]
ORA-01555 caused by SQL statement below (SQL ID: 9xw2k4bq1m7dc, Query Duration=232 sec, SCN: 0x0000000000a3c1f2):
SELECT D.ROWID AS RID, D.ITM_NO FROM CF10 H, CF11 D WHERE D.SLE_NO = H.SLE_NO AND H.SLE_DT >= '20230301'
[V$UNDOSTAT — 10:00 ~ 10:10 구간]
UNDOBLKS TXNCOUNT MAXQUERYLEN TUNED_UNDORETENTION UNXPSTEALCNT SSOLDERRCNT NOSPACEERRCNT
24,310 1,962 232 418 37 1 0
V$UNDOSTAT을 근거로 무엇이 '너무 오래되어' 없어졌는지, 1,000건마다 한 커밋이 왜 이를 막지 못했는지(오히려 거들었는지) 설명하시오.