대기 이벤트
- Oracle에서는 Wait Event , SQL Server에서는 Wait Type이라고 부른다.
👀 대기 이벤트의 탄생 배경
- 오라클은 역할 분담된 많은 프로세스(쓰레드)간 커뮤니케이션과 상호작용을 하면서 다른 프로세스 처리를 기다리는 상황이 자주 발생한다.
- 이 때마다 프로세스는 일 할 수 있는 조건이 충족 될 때까지 수면(Sleep) 상태에 빠지게 되는데 이게 곧 대기 이벤트(Wait Event)인 것! 이 때 상태 정보를 파일 혹은 SGA 메모리에 저장한다.
- 대기 이벤트는 원래 오라클 개발자들이 디버깅 용도로 개발하여 공유 자원에 대한 경합이나 기타 원인에 의한 대기가 발생할 때마다 로그를 생성 하도록 커널 코드에 추가 한것이다.
- 현재 OWI(Oracle Wait Interface) 이름으로 성능 관리 분야에 일대 변혁을 가져왔다.
- 대기 이벤트 수는 7.0은 100 여 개 , 9i는 400 여개 , 10g는 890 여개 , 11g는 1,100 여개 정도로 있다.
1. 시스템 커널 레벨 관점의 대기 이벤트
- 프로세스가 할 일을 모두 마쳤거나 다른 프로세스를 기다려야 하는 상황에서 CPU 를 낭비하지 않고 수면 상태로 빠진다.
- 시스템 커널 레벨 관점의 대기 이벤트 과정
1. 프로세스가 Wait Queue 로 옮겨진다.
- 이 때 OS 는 Wait Queue 내 프로세스에 CPU를 할당하지 않는다.
2. 선행 프로세스가 일을 마치면 OS에게 알린다. (Interrupted 상태)
3. OS는 기다리던 Wait Queue 내 프로세스를 Runnable Queue 에 옮긴다.
2. vmstat
- 서버의 가상 메모리 통계정보를 보기위한 명령어이다.
- 커널 스레드, 가상 메모리, 디스크, 트랩 및 CPU 활동에 대한 통계를 보고한다.
- 작성된 보고서는 시스템 로드 활동의 균형을 유지하는 데 사용된다.
- 시스템 전반에 대한 통계(모든 프로세서 중에서의 통계)는 비율로 표시된 값의 평균 또는 합계로 계산된다.
vmstat 구문
vmstat [ -f ] [ -i ] [ -s ] [ -I ] [ -t ] [ -v ] [ -w] [ -l ] [ { -p | -P } pagesize | ALL ] ALL ] [ PhysicalVolume ... ] [ Interval [ Count ] ]
- -t : 출력의 각 행 다음에 시간 소인을 출력하며 시간 소인은 HH:MM:SS 형식으로 표시된다.
- Interval에서 60 : 60초 간격으로 출력하도록 함
- Count에서 1000 : 한번에 1000개의 로우를 출력하도록 함
3. 대기이벤트 발생 시기
1) 자신이 필요로 하는 특정 리소스가 다른 프로세스에 의해 사용중일 때
- 자신이 읽으려는 버퍼에 다른 프로세스가 쓰기 작업을 진행 중일 때 마칠 때까지 기다린다.
buffer busy waits
latch free
enqueue
이벤트 등이 있다.
2) 다른 프로세스에 의해 선행작업이 완료되기를 기다릴 때
- DBWR가 LGWR가 일을 마칠 때까지 대기할 때
- DBWR가 Dirty 버퍼를 디스크에 기록할 때 LGWR가 로그 버퍼에 있는 Redo Entry를 Redo Log 파일에 기록하는 작업이 선행되야 한다.
- DBWR는 LGWR를 깨워 로그 버퍼를 비우라는 신호를 보내고 LGWR가 일을 마칠 때까지 대기한다.
write complete waits
checkpoint completed
log file sync
log file switch
이벤트 등이 있다.
3) 할 일이 없을 때 ( = idle 대기 이벤트)
- 서버 프로세스는 쿼리 결과를 사용자에게 전송하는 동안 Array 단위로 일을 처리하여 Array 크기만큼 데이터를 전송하면 다음 Fetch Call을 받을 때까지 기다린다.
- 쿼리 결과집합을 모두 전송한 후에는 Parse Call 또는 Execute Call을 받을 때까지 기다린다.
- 병렬 쿼리 수행시 일이 먼저 끝난 Slave 프로세스는 다른 Slave 들이 일 마칠 때까지 대기한다.
SQL*Net message from client
등이 있다.
4. 대기 이벤트 소멸 시기
1) 선행 작업이 끝난 경우
- 오라클 프로세스가 자신이 작업을 진행할 때 선행 프로세스가 먼저 점유하여 대기 상태에 빠질 경우 선행작업이 끝나고 나서 자신에게 알려주어 일을 할 때 소멸된다.
2) 타이머에 설정된 시간에 깨어나 선행 프로세스가 작업을 모두 마쳤는지 확인할 때
- 아직 리소스가 사용중 이면 다시 수면 상태로 빠진다.
- 잦은 대기 이벤트 발생도 문제지만 잦은 타임아웃은 더 문제가 된다. Latency가 증가하기 때문이다.
대기 이벤트별 timeout값
- DBWR, LGWR 상호 작용의 Timeout 은 둘다 3초
- LGWR 를 깨워 Redo 버퍼를 비우도록 할 때 발생하는 log file sync 의 Timeout 은 1초
- buffer busy wait 의 Timeout 은 1초
- enqueue 관련 Lock 대기 이벤트 의 Timeout 은 3초
3) 대기 상태에 빠진 프로세스가 기다리던 리소스를 사용할 수 있게 될 경우
4) 해야 할 일이 생겼을 경우
5. 래치와 대기 이벤트
-
앞으로 래치와 락이 헷갈리면 아래 짤을 떠올리면 좋다.왜냐고 ? 궁금하면 같이 한번 보시죱!😎
...래치는 아래 짤과 같다.
-
래치를 얻는 과정 자체가 경합은 아니다.
- 래치를 얻는 시도를 많이 했다고 해서 문제가 되는 건 아니다.즉 v$latch.gets 증가는 문제 가 되지 않음
-
접근 요청 횟수 보다, 접근 과정 중 다른 프로세스와 경합 발생 여부가 중요하다.
-
래치는 큐잉 메커니즘이 없다.⭐️
- 즉 줄을 서지 않는다는 말씀 ! 먼저 잡은 놈이 임자!!! 저 짤 그대로이다.
-
획득 성공 까지 반복 액세스를 시도하며 획득 우선권과 대기 순서 따위는 없다.⭐️
-
9i 까지는 래치 대기 이벤트가 latch free 하나 였으나, 10g 부터는 세분화 됨
latch: cache buffers chains
latch: library cache lock
등
5. v$latch (willing-to-wait 모드)
1) 파라미터 값 설명
gets
:: 래치 요청 횟수
misses
:: 래치를 요청 했으나, 자원이 사용중이라 첫 시도에서 래치를 얻지 못한 횟수
simple_gets
:: 첫 시도에서 곧바로 래치 획득에 성공한 횟수 (=gets - misses)
spin_gets
:: 첫 시도에서 래치를 얻지 못했으나, 이후 spin 중 래치 획득 한 횟수
spin
: CPU 점유 상태로 래치 획득 시도 반복 하는 것
sleeps
:: 래치를 얻지 못했고, 정해진 횟수(_spin_count=2000)만큼 spin 했는데도 얻지 못해 대기 상태로 빠진 횟수(latch free)