테마
한빛유통은 2022년 주문을 보관 DB로 옮긴 뒤 운영에서 지우기로 했다. DB 링크가 가끔 끊기므로 개발자는 5,000건씩 옮기고, 어디까지 옮겼는지를 체크포인트 테이블에 적어 끊기면 그다음부터 다시 돌게 했다. 일요일 밤 작업은 62회차 만에 '완료'로 끝났다. 다음 단계(운영 원본 삭제)는 건수 대조에서 멈췄다. 원본은 333,245건인데 보관본은 305,429건이었다. 박팀장: "에러도 없고 링크도 한 번도 안 끊겼다는데, 2만 8천 건이 어디로 갔습니까?"
T_ORD_BIG: 1,000,000행 · 5,826블록 · ORD_DT는 2022-01-01 ~ 2024-12-31이고 전부 자정이다(시분초 없음, 하루 약 913건) · 2022년 333,245건 · ORD_SEQ는 값이 유일하다(인덱스 없음)IX_ORD_BIG_DT_AMT (ORD_DT, ORD_AMT)T_ORD_ARC@ARC: 보관 DB의 보관 테이블(같은 컬럼). 작업 전에는 비어 있었고, 보관 DB를 쓰는 다른 작업은 없다.T_MIG_CKPT (JOB_NM, LAST_DT): 체크포인트 테이블(이 문제용). 작업 시작 전 LAST_DT는 2021-12-31이었다.-- 일요일 22:00 · 2022년 주문 보관 이관 (끊기면 같은 블록을 다시 실행하면 이어서 돈다)
DECLARE
v_last DATE;
v_rows NUMBER;
BEGIN
LOOP
SELECT LAST_DT INTO v_last FROM T_MIG_CKPT WHERE JOB_NM = 'ORD_ARC_2022';
INSERT INTO T_ORD_ARC@ARC (ORD_SEQ, CUS_ID, ORD_DT, ORD_ST, ORD_AMT)
SELECT ORD_SEQ, CUS_ID, ORD_DT, ORD_ST, ORD_AMT
FROM (SELECT ORD_SEQ, CUS_ID, ORD_DT, ORD_ST, ORD_AMT
FROM T_ORD_BIG
WHERE ORD_DT > v_last
AND ORD_DT < DATE '2023-01-01'
ORDER BY ORD_DT)
WHERE ROWNUM <= 5000;
v_rows := SQL%ROWCOUNT;
EXIT WHEN v_rows = 0;
UPDATE T_MIG_CKPT -- 이번에 옮긴 마지막 주문일
SET LAST_DT = (SELECT MAX(ORD_DT) FROM T_ORD_ARC@ARC)
WHERE JOB_NM = 'ORD_ARC_2022';
COMMIT;
END LOOP;
END;
[회차별 기록 — 체크포인트와 넣은 행]
회차 넣은 행 이번 회차의 마지막 ORD_DT (LAST_DT)
1 5,000 2022-01-06
2 5,000 2022-01-12
3 5,000 2022-01-17
… … …
61 5,000 2022-12-26
62 429 2022-12-31
63 0 → 끝 · 스케줄러 상태 SUCCEEDED · 링크 끊김 0번
[대조 — 원본 삭제 단계가 멈춘 이유]
원본 2022년 333,245 · 보관본 305,429 · 차이 27,816 → ORA-20010 (삭제 단계 대조 불일치)
하루 치가 일부만 들어간 날 61일 · 예) 2022-01-06 원본 911행, 보관본 433행
[회차 하나의 SELECT — DISPLAY_CURSOR(FORMAT => 'ALLSTATS LAST')]
------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 5000 |00:00:00.04 | 5031 |
|* 1 | COUNT STOPKEY | | 1 | | 5000 |00:00:00.04 | 5031 |
| 2 | VIEW | | 1 | 5000 | 5000 |00:00:00.04 | 5031 |
| 3 | TABLE ACCESS BY INDEX ROWID | T_ORD_BIG | 1 | 5000 | 5000 |00:00:00.03 | 5031 |
|* 4 | INDEX RANGE SCAN | IX_ORD_BIG_DT_AMT | 1 | 5000 | 5000 |00:00:00.01 | 18 |
------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<=5000)
4 - access("ORD_DT">:B1 AND "ORD_DT"<TO_DATE(' 2023-01-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
ORD_DT의 분포로 설명하시오.