테마
T3 — 배치 SLA 리포트 (템플릿)
14화에 제정했고, 15화에 2호를 내면서 9번 칸을 처음 채웠다. 배치(야간 적재 · 월말 정리 · 집계 체인 · 주간 보정)를 진단하거나 바꿀 때 쓴다. T1이 "이 SQL 한 번이 몇 블록을 읽는가"를 줄이는 문서라면, T3은 "이 체인이 정해진 창 안에 끝나는가"를 지키는 문서다. 목표가 반대다. 단건 SQL은 덜 읽으면 이긴다. 배치는 마감 안에 끝나고, 도는 동안 낮 업무를 막지 않고, 죽으면 다시 시작할 수 있어야 이긴다. 이 양식은 그 세 가지를 빠짐없이 적게 되어 있다.
왜 이 문서가 있는가
[주간 야간 체인] 일 22:00 시작 → 월 04:00 마감
로그: 시작 22:00:04 · 끝 09:12:37 ← 단계별 시각이 없다14화(6월 3일)에 체인이 마감을 다섯 시간 넘겼다. 그 주에 달라진 것은 월말 정리 하나뿐이었다. 그런데 운영 로그에 단계별 시각이 없어서 연습 DB에서 네 단계를 하나씩 다시 돌려 봐야 했다.
14화 실측 (ora-hanorder 복사본 · 단독 실행) | 경과 | redo |
|---|---|---|
| ① 재적재 100만: 일반 INSERT · 인덱스 3개 켠 채 | 329초 (그중 리두 로그 교체 대기 309.5초) | 916.6MB |
| ① 통계 수집 | 1.06초 | 1.4MB |
② 월말 이력 정리: DELETE 한 달 | 0.06초 | 4.84MB |
③ 월마감 집계: PARALLEL(8) (Free에서 Unused) | 0.05초 | — |
| ④ P1 정산 적재 10만 | 0.89초 | 28.66MB |
넘치게 한 것(②)과 창을 채운 것(①)이 달랐다. 단계별로 재지 않았다면 월말 정리만 고치고 다음 달에 또 넘쳤을 것이다. 무기(APPEND · 인덱스 끄고 켜기)로 329초를 5초로 줄였지만, 그 대신 도는 동안 테이블이 통째로 잠겼고, 인덱스가 꺼진 몇 초 동안 낮의 조회는 91 → 5,822로 나빠졌다. 마감 안에 끝나면 아무도 모르지만, 마감을 넘기면 낮 업무가 막힌다. 「동시 실행 영향」 칸은 그래서 있다.
배치 리포트에는 "얼마나 빨라졌나"가 아니라 "창 안에 끝나는가, 끝나지 않으면 무엇이 막히는가"를 적는다.
작성 규칙
| T0 측정 규약을 따른다 | "빨라졌다"는 쓰지 않는다. 초는 보조 지표다. redo · 블록 변경 · 처리 건수로 쓰고, 초에는 측정 조건(단독/동시 · 장비)을 붙인다 |
| 단계로 쪼갠다 | 체인 전체의 시작과 끝만으로는 원인을 찾을 수 없다. 단계마다 시작 · 끝 · 건수 · redo를 적는다 |
| 환경을 적는다 | 로그 모드(ARCHIVELOG 여부) · 리두 로그 크기 · 에디션(병렬 · 파티셔닝 가능 여부). 연습 DB의 초를 운영의 초로 옮기지 않는다 |
| 적재 방식을 적는다 | 일반 INSERT / APPEND / 인덱스 끄고 켜기 / 파티션 교체. 같은 인덱스라도 방식에 따라 값이 다르다 |
| 빈칸은 반려 사유다 | 특히 1 · 6 · 7 · 10번 칸 |
| 정합성 · 커밋 주기를 붙인다 | 08화 이후 모든 리포트에 붙이는 정합성 표 + 13화 「커밋 주기 기준」의 경로 |
양식
┌──────────────────────────────────────────────────────────────────────────────┐
│ T3 배치 SLA 리포트 — N호 문서번호 T3-___ │
├──────────────────────────────────────────────────────────────────────────────┤
│ 작성자 : ____________ 측정일 : __________ 측정 환경 : ____________________ │
└──────────────────────────────────────────────────────────────────────────────┘1. 배치와 창 ★
| 항목 | 내용 |
|---|---|
| 배치(체인) 이름 · 단계 수 | |
| 트리거 시각 · 마감 시각 | |
| 현재 소요 · 여유 시간 (마감 − 끝) | 음수면 초과 |
| 같은 창에서 도는 다른 배치 · 자동 작업 | 자동 통계 수집 창 · 백업 · 다른 체인 (10화) |
2. 측정 환경
| 항목 | 내용 |
|---|---|
컨테이너 · 버전 · cpu_count | |
로그 모드 · FORCE_LOGGING · 온라인 리두 로그 크기 × 개수 | 연습 DB NOARCHIVELOG · 10MB × 2 (14화) |
| 병렬 · 파티셔닝 가능 여부 | 연습 DB(Free)는 병렬 불가 · 파티셔닝 가능 |
| 단독 실행 / 동시 실행 |
3. 단계 분해 ★
| 단계 | 처리 건수 | 경과 | redo | undo | 블록 변경 | 주된 대기 | 출처(스크립트 · 로그) |
|---|---|---|---|---|---|---|---|
대기 칸에
log file switch (checkpoint incomplete)가 크면 CPU가 아니라 리두 로그가 비기를 기다리는 것이다. 리두를 줄이는 쪽(적재 방식)을 먼저 손본다.
4. 처리량 — 건당 비용
| 항목 | 지금 | 바꾼 뒤 |
|---|---|---|
| 초 / 건 (보조) | ||
| redo / 건 | ||
| 블록 변경 / 건 |
5. 자원 소비
| 항목 | 지금 | 바꾼 뒤 |
|---|---|---|
| redo size | ||
| undo change vector size | ||
| TEMP · PGA 피크 (정렬 · 인덱스 재생성) | ||
세그먼트 크기 변화 (USER_SEGMENTS) |
6. 실패 · 재기동 · 멱등성 ★
| 항목 | 내용 |
|---|---|
| 중간에 죽으면 남는 상태 | 전부 롤백 / 반쯤 반영 (13화) |
| 재기동 지점 | 어디서부터 다시 돌리나 · 체크포인트 테이블이 있나 |
| 멱등한가 | 두 번 돌려도 같은가(TRUNCATE부터 · MERGE · 이미 처리한 키 건너뛰기) |
| 「커밋 주기 기준」 경로 | #1 집합 연산 · #2 fetch across commit · #3 큰 언두 · #4 그 밖 |
7. 동시 실행 영향 ★ — 마감을 넘기면 무엇이 막히나
| 항목 | 내용 |
|---|---|
| 테이블 락 | APPEND면 TM LMODE 6. 커밋할 때까지 다른 세션의 DML 불가 |
| 인덱스 상태 | 끄고 켜기면 꺼진 동안 조회가 조용히 다른 길로 간다(Buffers N → M을 적는다) · UNIQUE면 DML이 ORA-01502 |
| 읽는 쪽이 보는 것 | 반쯤 적재(N건마다 커밋) / 0건 → 전부(한 문장) |
| 대기 이벤트 | enq: TM - contention · log file switch … · buffer busy waits |
8. 추세 — 몇 달 뒤 다시 넘치나
여유 시간(초) ÷ [ 건당 비용(초/건) × 월 증가 건수 ] = 다시 넘칠 때까지 남은 달 수| 항목 | 값 |
|---|---|
| 월 증가 건수 (근거) | |
| 건당 비용 (근거: 운영 실측) | |
| 남은 달 수 |
운영의 단계별 시각이 없으면 이 칸에는 "측정 불가"라고 쓰고, 재측정 계획(12번)에 단계별 기록을 넣는다. 연습 DB의 건당 비용으로 운영을 추정하지 않는다.
9. 【15화】 PL/SQL 호출 통계
10046 + TKPROF로 채운다(15화 실습/02). V$MYSTAT의 recursive calls로 대조한다.
| 항목 | 지금 | 바꾼 뒤 |
|---|---|---|
| User Call: NON-RECURSIVE Parse · Execute · Fetch | ||
| Recursive Call: RECURSIVE Execute · Fetch | ||
행마다 호출된 한 건 조회: Fetch ≈ Execute ≈ rows인 문장과 그 횟수 | ||
| 구동 커서의 배열 크기: rows ÷ Fetch | ||
| 행마다 호출한 함수의 호출 수 (함수 안 SELECT의 Execute · HPROF) | ||
| SQL ↔ PL/SQL 왕복 절감 (recursive calls N → M) |
⚠️ TKPROF에는 트레이스를 켜기 전에 열린 커서가 빠진다(
PARSING IN CURSOR줄이 없어서 버려진다 · 15화 실측: 함수 안 SELECT 2,000번이 표에 없었다). 합계가 이상하게 작으면 raw 파일의EXEC줄이나V$SQL.EXECUTIONS,DBMS_HPROF로 센다. 함수를 문장 안으로 옮겨 '한 문장'이 됐어도 이 칸을 채운다. 함수 호출 수가 그대로면 루프가 문장 안으로 숨은 것이다(15화:MERGE+ 함수 = 100,020번).
10. 정합성 회귀 ★ (08화 이후 필수)
「정합성 회귀 체크리스트」의 A~H를 붙인다. 배치에서는 특히 다음을 본다.
| # | 배치에서 보는 것 |
|---|---|
| A | 기준은 원장(입력 전체)이다. 원래 판과만 대조하면 원래 판이 빠뜨린 것은 끝내 보이지 않는다(15화: rev00과 대조하면 99,850 = 99,850으로 '통과' · 원장과 대조하니 170건이 빠짐) |
| B | 바꾼 판과 원래 판의 결과 테이블: 건수 · 합계 · 양방향 MINUS · 키 중복, 그리고 원장 = 처리 + 반송(빠진 것 0) |
| E | 번호 · 순서가 ORDER BY 없이 '읽은 순서'로 붙는가 · 반쯤 반영 |
| H | 그 테이블을 읽는 화면 · 다음 배치가 적재 중에 무엇을 보나 |
11. 개선 이력
| 리비전 / 방식 | 날짜 | 경과 | redo | 비고 |
|---|---|---|---|---|
12. 재측정 계획 · 재발방지
| # | 조치 | 담당 | 기한 | 검증 | 리스크 |
|---|---|---|---|---|---|
| ← 13화: 비우면 다음 장애가 된다 |
금지어
"빨라졌다", "느리다", "오래 걸린다"는 쓰지 않는다. 모두 단계별 N → M으로 쓰고, 초 옆에는 측정 환경(연습 DB · 단독 · 로그 모드)을 붙인다. "병렬로 돌리면 된다": 그 DB에서 병렬이 되는지(에디션), 된다면 CPU 몇 개를 누구와 나눠 쓰는지 먼저 적는다. 재 보지 못한 힌트를 근거로 쓰지 않는다(14화: Free에서 PARALLEL(8) = U - Unused).
자매 문서
- T1 단건 SQL 튜닝 리포트: 02화 제정
- T2 인덱스·힌트 변경 승인서: 04화 제정 · 14화 개정(「적재 비용」 칸)
- T4 장애 포스트모템: 12화 제정
- 커밋 주기 기준(13화 제정) · 통계 수집 정책서(10화 제정)
개정 이력: 14화에 제정했다(1호 = 6월 2일 일요일 밤 주간 체인, 마감 5시간 초과). 15화 2호는 주간 정산 보정 배치다. 9번 칸을 처음 채웠고(recursive calls 301,187 → 2,457 · 행마다 호출된 한 건 조회 100,020 → 0), 9번 칸에 '행마다 호출된 한 건 조회'와 'TKPROF에서 빠지는 커서' 줄을 더했다. 10번 정합성에는 '직전 판과 대조하면 통과해 버린다(A)'를 실례로 넣었다.
18화 3호는 월마감 집계 낮 재실행이다. 7번 「동시 실행 영향」에 리소스 플랜 네 판을 재서 넣고, '플랜을 근거로 낮 실행을 허락하지 않는다'고 판정했다(이 장비에서는 약속과 다르게 동작했고, 원인은 확인하지 못했다).