DB Study

12장. AWR과 대기 이벤트 — 모니터링

"DB가 느려요"라는 신고 앞에서 감으로 헤매지 않는 방법 — Oracle은 모든 기다림을 이름 붙여 기록합니다. 그 기록을 읽는 법을 배웁니다.

중급 ⏱ 약 30분 🎬 애니메이션 3개 선수 지식: 2·7·8장
🧭
이 장에서 배우는 것

① 대기 이벤트(wait event)라는 진단 언어와 대표 이벤트 5종 ② v$session·v$sql·ASH로 "지금"을 보는 법 ③ AWR 스냅샷 원리와 리포트 읽는 순서 ④ ADDM·Statspack까지, 상황별 도구 선택

12.1 대기 이벤트 — Oracle의 진단 언어

세션은 CPU에서 일하고 있거나, 무언가를 기다리고 있거나 둘 중 하나입니다. Oracle은 기다림의 종류마다 이름을 붙여 놓았습니다 — 이것이 대기 이벤트(wait event)입니다. "느리다"는 막연한 증상이 대기 이벤트를 보는 순간 "디스크 I/O를 기다린다", "락을 기다린다", "커밋 기록을 기다린다"라는 구체적인 병목 유형으로 번역됩니다.

현장에서 만나는 빈도순으로, 이 다섯 개만 외워도 절반은 해결됩니다.

대기 이벤트전형적 원인
db file sequential read싱글 블록 디스크 읽기 (이름과 달리 주로 인덱스 경유 접근)인덱스 스캔 + 테이블 랜덤 접근이 많음. 과하면 나쁜 CF·비효율 인덱스 의심
db file scattered read멀티 블록 읽기를 버퍼 캐시 여기저기(scattered)에 적재Full Table Scan / Index Fast Full Scan — 풀스캔이 많다는 신호
log file sync커밋 후 LGWR가 redo를 디스크에 쓸 때까지 대기커밋이 너무 잦음(루프 내 건별 커밋), redo 디스크가 느림
buffer busy waits같은 버퍼 블록을 두고 세션들이 경합특정 블록에 삽입/변경 집중 (예: 시퀀스 PK 인덱스의 오른쪽 끝 블록)
enq: TX - row lock contention다른 트랜잭션이 잡은 행 락을 대기커밋하지 않는 긴 트랜잭션, 같은 행 동시 갱신 (8장 참고)
📞 "화면이 느려요!" 증상만 있고 원인은 미궁 SELECT sid, event, state FROM v$session event = db file scattered read 그 세션이 "지금" 기다리는 것 sequential read → 인덱스 랜덤 I/O → 인덱스/CF 점검 scattered read ✔ → Full Scan 다발 → 어떤 SQL이? 추적 enq: TX / log file sync → 락 경합 / 커밋 폭주 → 블로킹 세션/커밋 습관 v$session.sql_id → v$sql: 문제 SQL 텍스트·실행횟수·읽은 블록 확인 SELECT * FROM orders WHERE TO_CHAR(order_dt,...) = ... ← 범인 검거 실행계획 확인 → 컬럼 가공 제거 + 인덱스 → scattered read 소멸 ✔

12.2 "지금"을 보는 창 — v$session, v$sql, ASH

실시간 진단의 3종 세트입니다. v$로 시작하는 뷰들은 SGA의 현재 상태를 보여주는 동적 성능 뷰입니다.

-- ① 지금 활동 중인 세션은 무엇을 기다리나
SELECT sid, serial#, username, sql_id, event, state,
       seconds_in_wait, blocking_session
FROM   v$session
WHERE  status = 'ACTIVE' AND username IS NOT NULL;

-- ② 그 세션이 돌리는 SQL의 정체 (sql_id로 조인)
SELECT sql_id, executions, elapsed_time/1e6 AS elapsed_sec,
       buffer_gets, disk_reads, sql_text
FROM   v$sql
WHERE  sql_id = '&sql_id';

순간을 보는 v$session의 약점은 "아까 무슨 일이 있었는지"를 모른다는 것. 그래서 Oracle은 ASH(Active Session History, v$active_session_history)를 둡니다 — 1초마다 모든 활성 세션의 스냅샷을 메모리 버퍼에 기록해 두는 블랙박스입니다. "10분 전 그 순간, 누가 무엇을 기다렸나"를 SQL로 되감아 볼 수 있습니다.

-- 최근 10분간 대기 이벤트 상위 집계 (ASH)
SELECT event, COUNT(*) AS samples   -- 샘플 수 ≈ 소요 시간(초)
FROM   v$active_session_history
WHERE  sample_time > SYSDATE - 10/1440
GROUP BY event ORDER BY samples DESC;
⚠️
라이선스 주의 — Diagnostics Pack

ASH·AWR·ADDM은 Enterprise Edition + Diagnostics Pack 라이선스가 있어야 사용할 수 있습니다. v$active_session_history를 조회하는 것만으로도 팩 사용으로 간주됩니다. 라이선스가 없다면 12.5절의 Statspack이 대안입니다.

12.3 AWR — 성능의 건강검진 기록부

AWR(Automatic Workload Repository)은 인스턴스의 성능 통계를 주기적으로 스냅샷으로 찍어 SYSAUX 테이블스페이스에 보관하는 저장소입니다. 기본 설정은 1시간 간격 스냅샷, 8일 보관이며 MMON 백그라운드 프로세스가 수행합니다. 리포트는 "두 스냅샷 사이의 차이"로 만들어집니다.

09:00 10:00 11:00 12:00 13:00 14:00 MMON이 기본 1시간마다 스냅샷 → SYSAUX에 저장 (기본 8일 보관) 🔥 11:20~12:40 장애 구간 begin snap end snap 리포트 = 두 스냅샷의 누적 통계 차이 (11:00→13:00) @?/rdbms/admin/awrrpt.sql 실행 → 구간을 감싸는 스냅샷 쌍 선택이 정확도의 전부

리포트 읽는 순서 — 위에서 아래로 좁혀가기

  1. Top 10 Foreground Events by Total Wait Time — DB Time을 무엇이 먹었나. CPU가 상위인 것은 정상일 수 있고, I/O·락 이벤트가 상위면 그것이 병목 유형입니다.
  2. SQL ordered by Elapsed Time / Gets / Reads — 병목 유형을 만든 구체적인 SQL을 찾습니다. 보통 상위 몇 개가 전체의 대부분을 차지합니다.
  3. 해당 SQL의 실행계획(DBMS_XPLAN.DISPLAY_AWR 또는 DISPLAY_CURSOR)으로 내려가 원인을 확정합니다.
💡
DB Time이라는 물통

AWR의 핵심 지표 DB Time = 모든 세션이 DB에서 소비한 시간(CPU + 대기)의 총합입니다. 진단이란 결국 "DB Time이라는 물통을 어떤 이벤트가, 어떤 SQL이 채웠는가"를 추적하는 일입니다. Top Events에서 유형을, SQL ordered by에서 범인을 찾는 순서가 그래서 성립합니다.

12.4 사례 연구 — log file sync 급증

가장 교육적인 단골 사례로 흐름을 연습해 봅시다. 어느 날 오후, 갑자기 모든 화면의 저장 버튼이 느려졌습니다.

평소 세션: COMMIT LGWR redo 기록 건당 대기 1ms 미만 — 아무도 못 느낌 배포 이후 FOR r IN c LOOP UPDATE ...; COMMIT; ← 루프 안! END LOOP; -- 50만 회 반복 커밋 50만 번 = LGWR 디스크 기록 확인 50만 번 모든 세션의 event: log file sync 폭증 📈 — 남의 커밋까지 줄을 선다 진단: AWR Top Events 1위 log file sync + user commits 통계 급증 → 커밋 폭주 확정 해결: 루프 밖 배치 커밋으로 수정 (redo 디스크가 느린 경우라면 스토리지 개선)

12.5 도구 정리 — ADDM과 Statspack까지

도구보는 것언제 쓰나라이선스
v$session지금 이 순간의 세션 상태실시간 장애 대응 첫 조회기본 포함
v$sql공유 풀의 SQL별 누적 통계무거운 SQL Top-N 추출기본 포함
ASH1초 단위 활성 세션 이력"몇 분 전 순간"의 정밀 분석Diagnostics Pack
AWR시간 단위 스냅샷 리포트구간 비교·사후 분석·추세Diagnostics Pack
ADDMAWR을 분석한 자동 진단 보고서스냅샷 생성 시 자동 실행 — 권고사항 훑어보기용Diagnostics Pack
StatspackAWR의 전신 격 수동 스냅샷 도구Standard Edition 등 팩 라이선스가 없을 때의 무료 대안기본 포함(수동 설치)

ADDM(Automatic Database Diagnostic Monitor)은 AWR 스냅샷이 생성될 때마다 자동으로 돌면서 "이 구간의 DB Time을 가장 많이 잡아먹은 원인과 권고"를 문장으로 뽑아줍니다. 권고를 맹신하기보다 분석의 출발점으로 삼는 것이 좋습니다. Statspack은 스냅샷을 수동(또는 잡 스케줄)으로 찍고 spreport.sql로 리포트를 만드는 무료 도구로, 리포트 구조와 읽는 순서는 AWR과 유사합니다.

🐘
PostgreSQL과 비교하며 읽기

PG의 pg_stat_activity(wait_event 컬럼)가 v$session, pg_stat_statements가 v$sql에 해당합니다(PG 14장 모니터링). 반면 ASH·AWR처럼 이력을 자동 축적하는 내장 장치는 PG 본체에 없어서 별도 확장/외부 도구로 보완합니다 — Oracle 모니터링 스택의 완성도가 돋보이는 지점입니다.

✍️ 이해도 체크

AWR 리포트에서 db file scattered read가 Top Events 1위였습니다. 다음으로 봐야 할 곳과 그 이유는?
✅ scattered read = 멀티블록 읽기 = Full Scan 계열이 많다는 "유형" 정보입니다. 유형을 알았으면 다음은 "누가?"입니다 — SQL ordered by 섹션에서 디스크 읽기가 큰 SQL을 특정하고, 그 실행계획으로 내려가 인덱스·통계·SQL 수정 여부를 판단합니다.
배포 직후 모든 세션에서 log file sync 대기가 급증했습니다. 가장 유력한 원인은?
✅ log file sync는 "커밋 → LGWR 기록 완료 대기"입니다. 갑자기 급증했고 배포와 시점이 겹친다면 커밋 횟수 폭증(루프 내 커밋)이 최우선 용의자입니다. AWR의 user commits 통계로 확증할 수 있습니다. 풀스캔·통계 문제는 각각 scattered read, 특정 SQL의 성능 저하로 나타납니다.