1. DBA_HIST_ACTIVE_SESS_HISTORY란?
- 무엇?
V$ACTIVE_SESSION_HISTORY(ASH)의 내용을 AWR 스냅샷에 주기적으로 저장해 두는 히스토리 뷰
→ “과거의 ASH”라고 보면 됨. - 기본 개념
- ASH는 1초마다 “지금 active 상태인 세션”을 샘플링해서 한 줄씩 적재.
- 이 중 일부가 AWR 스냅샷에 저장되면서
DBA_HIST_ACTIVE_SESS_HISTORY에 남음. - 각 로우 = “특정 시점에 active였던 한 세션의 스냅샷”.
- 주의 (라이선스)
- ASH, AWR,
DBA_HIST_*뷰 직접 조회는 Diagnostics Pack 라이선스에 포함되는 기능. - 운영 DB에서 활용할 땐 반드시 라이선스 보유 여부를 확인해야 함.
- ASH, AWR,
- 현재 ASH vs. 히스토리 ASH
- 현재 시점 중심 →
V$ACTIVE_SESSION_HISTORY - 과거 시점까지 포함한 장기 히스토리 →
DBA_HIST_ACTIVE_SESS_HISTORY
- 현재 시점 중심 →
2. 이 뷰로 볼 수 있는 주요 분석 관점
- 시간대별 부하 패턴 분석 (피크 타임, CPU vs Wait 비율)
- Top SQL / Top 세션 분석 (DB Time, Active Sample 기준)
- 대기 이벤트 / Wait Class 분석 (IO, Concurrency, Network 등)
- 락/Blocking Session, 경합 상황 분석
- RAC 환경에서 인스턴스/GC 관련 분석
- 사용자/모듈/서비스 관점의 업무 트래픽 분석
- 실행 계획 변경·성능 저하 전후 분석
- 에러/장애 발생 시점 근원 원인 분석
3. 시간대별 부하 패턴 분석
3-1. 피크 타임과 Active Session 수준
sample_time을 기준으로 일정 단위(예: 1분)로 묶어서
시간대별 Active Session 수를 보면, 피크 구간을 직관적으로 볼 수 있음.
SELECT
TRUNC(sample_time, 'MI') AS tm, -- 분 단위로 자르기
COUNT(*) AS active_sess, -- 전체 active 샘플 수
SUM(CASE WHEN session_state = 'ON CPU' THEN 1 ELSE 0 END) AS cpu_sess,
SUM(CASE WHEN session_state = 'WAITING' THEN 1 ELSE 0 END) AS wait_sess
FROM dba_hist_active_sess_history
WHERE sample_time BETWEEN
TO_DATE(:from, 'YYYYMMDDHH24MISS')
AND TO_DATE(:to, 'YYYYMMDDHH24MISS')
GROUP BY TRUNC(sample_time, 'MI')
ORDER BY tm;
이걸로 할 수 있는 분석:
- 언제 사용자가 몰리는지 (피크 타임)
- 그 피크 타임에
- CPU에 물려 있는지
- Wait(대기)에 묶여 있는지
→ CPU 부족인지, IO/락/네트워크 문제인지 1차 감이 옴.
4. Top SQL / Top 세션 분석
4-1. “DB Time에 많이 기여한 SQL” 찾기
ASH 샘플 개수는 곧 “해당 SQL이 Active 상태였던 시간”에 비례하므로
샘플 수를 기준으로 Top SQL을 뽑을 수 있음.
SELECT
sql_id,
COUNT(*) AS active_samples,
ROUND(COUNT(*) / 60, 1) AS active_minutes
FROM dba_hist_active_sess_history
WHERE sample_time BETWEEN
TO_DATE(:from, 'YYYYMMDDHH24MISS')
AND TO_DATE(:to, 'YYYYMMDDHH24MISS')
AND sql_id IS NOT NULL
GROUP BY sql_id
ORDER BY active_samples DESC
FETCH FIRST 10 ROWS ONLY;
이걸로 할 수 있는 것:
- 특정 시간 구간 동안 DB Time을 많이 먹은 SQL 후보 찾기
- AWR SQL 리포트(
DBA_HIST_SQLSTAT)의 Top SQL과 교차 확인 - 장애 발생 시간대에 어떤 SQL이 가장 오래, 많이 돌았는지 파악
4-2. 특정 세션/사용자 관점에서 분석
예를 들어 특정 사용자의 세션이 느렸다고 하면:
SELECT
sample_time,
session_id, session_serial#,
sql_id,
event,
session_state,
module, action,
machine, program
FROM dba_hist_active_sess_history
WHERE sample_time BETWEEN
TO_DATE(:from, 'YYYYMMDDHH24MISS')
AND TO_DATE(:to, 'YYYYMMDDHH24MISS')
AND user_id = (SELECT user_id FROM dba_users WHERE username = 'APP_USER')
ORDER BY sample_time;
이걸로 할 수 있는 것:
- 그 사용자의 세션이 언제 어떤 SQL을 실행했고, 어떤 이벤트로 기다렸는지 타임라인으로 확인
- 클라이언트
MODULE / ACTION / MACHINE / PROGRAM기준으로 어떤 배치/어떤 화면이 문제였는지 추적
5. Wait Event / Wait Class 분석
5-1. Top Wait Event
SELECT
wait_class,
event,
COUNT(*) AS samples
FROM dba_hist_active_sess_history
WHERE sample_time BETWEEN
TO_DATE(:from, 'YYYYMMDDHH24MISS')
AND TO_DATE(:to, 'YYYYMMDDHH24MISS')
AND session_state = 'WAITING'
GROUP BY wait_class, event
ORDER BY samples DESC
FETCH FIRST 15 ROWS ONLY;
이걸로 할 수 있는 것:
- IO(
User I/O,System I/O),
Concurrency, Application, Network 등 Wait Class별 비중 확인 - 대표적인 이벤트(예:
db file sequential read,enq: TX - row lock contention등) 파악 - “CPU 문제인지, IO 문제인지, 락 문제인지”를 그 시간 구간에 대해 정리 가능
5-2. 특정 Wait Class만 집중 분석
예: 락/경합 관련만 보고 싶을 때:
SELECT
event,
COUNT(*) AS samples
FROM dba_hist_active_sess_history
WHERE sample_time BETWEEN
TO_DATE(:from, 'YYYYMMDDHH24MISS')
AND TO_DATE(:to, 'YYYYMMDDHH24MISS')
AND session_state = 'WAITING'
AND wait_class = 'Concurrency'
GROUP BY event
ORDER BY samples DESC;
6. 락 / Blocking Session 분석
DBA_HIST_ACTIVE_SESS_HISTORY에는 blocking 세션 정보도 같이 찍힘.
SELECT
sample_time,
session_id, session_serial#,
sql_id,
event,
blocking_session,
blocking_session_serial#,
blocking_inst_id
FROM dba_hist_active_sess_history
WHERE sample_time BETWEEN
TO_DATE(:from, 'YYYYMMDDHH24MISS')
AND TO_DATE(:to, 'YYYYMMDDHH24MISS')
AND session_state = 'WAITING'
AND blocking_session IS NOT NULL
ORDER BY sample_time;
이걸로 할 수 있는 것:
- “그 시간에 어떤 세션이 다른 세션들을 막고 있었는지” 추적
blocking_session/blocking_inst_id를 기준으로- 블로킹 세션의 SQL, 모듈, 사용자까지 역추적 (다시
DBA_HIST_ACTIVE_SESS_HISTORY를 자기 자신과 조인)
- 블로킹 세션의 SQL, 모듈, 사용자까지 역추적 (다시
- 이미 지나간 시간대의 락 문제라도, ASH 히스토리만 남아 있다면 어느 정도 복원 가능
7. RAC 환경 / 멀티 인스턴스 분석
RAC 환경에서는 instance_number, blocking_inst_id, GC 관련 이벤트 등을 활용해서
인스턴스 간 부하 편차 및 Global Cache 병목을 볼 수 있음.
7-1. 인스턴스별 Active Session 비교
SELECT
instance_number,
COUNT(*) AS active_samples
FROM dba_hist_active_sess_history
WHERE sample_time BETWEEN
TO_DATE(:from, 'YYYYMMDDHH24MISS')
AND TO_DATE(:to, 'YYYYMMDDHH24MISS')
GROUP BY instance_number
ORDER BY instance_number;
→ 특정 인스턴스만 유난히 부하가 높은지 확인.
7-2. GC 이벤트(예: gc cr request) 비중
SELECT
instance_number,
event,
COUNT(*) AS samples
FROM dba_hist_active_sess_history
WHERE sample_time BETWEEN
TO_DATE(:from, 'YYYYMMDDHH24MISS')
AND TO_DATE(:to, 'YYYYMMDDHH24MISS')
AND event LIKE 'gc %'
GROUP BY instance_number, event
ORDER BY samples DESC;
→ RAC에서 자주 문제 되는 interconnect / gc 관련 병목의 정도와 위치 확인.
8. 사용자 / 모듈 / 서비스 관점 분석
애플리케이션 튜닝에서는 “SQL_ID”뿐 아니라
어떤 화면/어떤 배치/어떤 서비스가 문제인지 보는 것이 더 현실적일 때가 많음.
DBA_HIST_ACTIVE_SESS_HISTORY에는 아래와 같은 정보가 들어있음:
user_id(→DBA_USERS조인해서 사용자명)module,actionclient_idmachine,programservice_hash(서비스 별로도 집계 가능)- CDB 환경이라면 PDB 관련 컬럼도 버전에 따라 존재
예: 모듈별 부하
SELECT
NVL(module, 'UNKNOWN') AS module,
COUNT(*) AS active_samples
FROM dba_hist_active_sess_history
WHERE sample_time BETWEEN
TO_DATE(:from, 'YYYYMMDDHH24MISS')
AND TO_DATE(:to, 'YYYYMMDDHH24MISS')
GROUP BY NVL(module, 'UNKNOWN')
ORDER BY active_samples DESC
FETCH FIRST 10 ROWS ONLY;
→ 어떤 모듈(예: ‘주문조회’, ‘배치_월마감’)이 DB 부하를 많이 유발하는지 파악.
9. 실행 계획 변경 / 성능 저하 전후 비교
같은 SQL_ID라 하더라도, 시점에 따라 plan_hash_value가 달라질 수 있음.
이걸 이용해서 실행 계획 변경 전후 성능 차이를 추적 가능.
SELECT
sql_id,
plan_hash_value,
COUNT(*) AS active_samples
FROM dba_hist_active_sess_history
WHERE sample_time BETWEEN
TO_DATE(:from, 'YYYYMMDDHH24MISS')
AND TO_DATE(:to, 'YYYYMMDDHH24MISS')
AND sql_id = :sql_id
GROUP BY sql_id, plan_hash_value
ORDER BY active_samples DESC;
활용 포인트:
- 특정 SQL_ID에 대해 과거에는
plan_hash_value = A였고, 최근에는B로 바뀌었다면- 두 계획의 Active Sample 수를 비교 → 어느 쪽이 더 무거운지
- AWR SQL Plan, Explain Plan과 연계해서 구체적인 플랜 비교
- 통계 갱신, 인덱스 생성/삭제, 파라미터 변경 이후 플랜 변화 감지
10. 에러 / 장애 시점 분석 (ORA-xxxx 대응)
alert.log나 모니터링 시스템에서 에러 시각만 알고 있을 때,
그 시각 전·후로 DBA_HIST_ACTIVE_SESS_HISTORY를 보면 “그때 DB 안에서 무슨 일이 있었는지”를 복원할 수 있음.
예: ORA-04036 (PGA_AGGREGATE_LIMIT) 발생 시점 전후로,pga memory operation 이벤트를 기준으로 Top SQL을 뽑는 식.
SELECT
sql_id,
COUNT(*) AS samples
FROM dba_hist_active_sess_history
WHERE sample_time BETWEEN
TO_DATE(:error_time, 'YYYYMMDDHH24MISS') - INTERVAL '10' MINUTE
AND TO_DATE(:error_time, 'YYYYMMDDHH24MISS') + INTERVAL '5' MINUTE
AND event = 'pga memory operation'
GROUP BY sql_id
ORDER BY samples DESC;'📁 Database > Oracle' 카테고리의 다른 글
| [Oracle] 테이블명 변경 시 오브젝트 타입별 상태 영향도 파악(VALID → INVALID / 다시 VALID 되는 조건) (0) | 2025.12.04 |
|---|---|
| [Oracle] ORA-08177: can't serialize access for this transaction (0) | 2025.11.17 |
| [Oracle] Consistent Read(CR) / Current Read(CU) (0) | 2025.11.13 |
| [Oracle] 쿼리 수행 후 실행 통계 확인 (SET AUTOTRACE ON STATISTICS) (0) | 2025.11.13 |
| [Oracle] Lock과 Latch (0) | 2025.11.12 |