대기 이벤트

  • 다른 프로세스가 일을 마치 때까지 기다려야만 하는 사황이 자주 발생한다. 오라클 프로세스는 일을 계속 진행할 수 있는 조건이 충족 될 때까지 수면 상태에 빠지는데,
    이런 현상이 발생하는 것을 '대기 이벤트( Wait Event )라고 부른다.
  • 오라클 개발자들이 디버깅 용도로 개발한 것이라고 한다.
  • 공유자원에 대한 경합이나 기타 원인에 의한 대기가 발생할 때마다 관련 로그를 생성하도록 커널 코드에 기능을 추가했던 것이고, 오늘에 이르러 OWI라는 이름을
    덧입으면서 성능관리 분야에 일대 변혁을 가져오게 되었다.
  • 7.0 : 100여개, 10g : 890, 11g : 960

시스템 커널 레벨

  • 프로세스가 할 일을 모두 마쳤거나 다른 프로세서를 기다려야 하는 상황에서 CPU를 쥔 채 대기하면
    불필요하게 CPU 자원을 낭비하는 것이므로 CPU를 OS에 반환하고 수면상태로 빠지는 것을 말한다.
    선행 프로세스가 일을 마치면 OS에게 그 사실을 알려 자시늘 기다리던 수면 상태의 프로세스를 깨우도록
    신호를 보낸다. 그러면 OS는 그 프로세스를 runnable queue에 옮김으로써 가능한 빨리 CPU를 할당 받아
    일을 재개할 수 있도록 스케쥴링한다.

수면 상태.?

  • 프로세스가 wait queue로 옮겨지는 것을 말하며, wait queue에 놓인 프로세스에게는 CPU를 할당해 줄 필욕 없으므로
    OS는 해당 프로세스를 슼케쥴링 대상에서 제외시킨다.

vmstat( 저희는 리눅스라 ㅠ 봉래형님 솔라리스 빼옴 )

{CODE:SQL}
kthr memory page disk faults cpu
r b w swap free re mf pi po fr de sr cd -- -- -- in sy cs us sy id
0 0 0 1880820 56856 1 7 0 0 0 0 0 13 0 0 0 463 330 218 1 0 98
0 0 0 1895012 56452 0 44 0 0 0 0 0 0 0 0 0 497 998 257 0 0 99
0 0 0 1894932 56420 0 0 0 0 0 0 0 5 0 0 0 525 1149 303 0 0 99
0 0 0 1894932 56420 0 0 0 0 0 0 0 0 0 0 0 498 1130 258 0 0 100
0 0 0 1894932 56420 0 0 0 0 0 0 0 0 0 0 0 509 811 253 0 0 100
0 0 0 1894932 56420 0 0 0 0 0 0 0 2 0 0 0 546 901 304 1 0 99
0 0 0 1894912 56400 0 0 0 0 0 0 0 0 0 0 0 505 1201 261 0 0 100
0 0 0 1894912 56400 0 0 0 0 0 0 0 0 0 0 0 506 748 271 0 0 100
0 0 0 1894912 56400 0 0 0 0 0 0 0 2 0 0 0 521 1172 318 0 1 99
1 0 0 1894912 56400 0 0 0 0 0 0 0 0 0 0 0 491 891 246 0 0 99
0 0 0 1894912 56404 0 0 0 0 0 0 0 0 0 0 0 518 1039 273 0 0 99
0 0 0 1894912 56404 0 0 0 0 0 0 0 2 0 0 0 526 1218 314 0 0 100
{CODE}

  • r : 현재 일을 수행 중이거나 runnable queue에서 CPU 리소스를 기다리는 프로세스 개수다. 이 수치가 CPU 개수를 초과하고 CPU 사용률이 100%에 근접한다며
    CPU병목현상이 발생한 것으로서, 할 일이 산적해 있는데 프로세스들이 빨리빨리 CPU를 할당 받지 못해 runnable queue에서 오래 대기하고 있음을 의미한다.
  • w : wait queue에 놓인 프로세스 개수를 의미한다. 즉 Sleep 상태의 프로세스 개수로서 이 값이 큰 것도 병목일 수 있다. 특히, 오라클 입장에서는 대기 이벤트가
    많이 발새한 것이므로 어떤 종류의 대기 이벤트가 발생 중인지 뷰를 통해 확인해 봐야 한다.
  • id : 여유자원
  • pi : paging
  • po : paging

대기이벤트로 볼수없는것..

  • SQL*Net message from client, SQL*Net more data from client : 서버 프로세스가 사용자의 명령이나 신호를 기다릴 때
  • pmon timer, smon timer, px idle : 서버 프로세스가 할 일이 없기 때문에 발생하는 idle대기 이벤트

(2) 대기 이벤트는 언제 발생할까?

1. 자신이 필요로 하는 특정 리소스가 다른 프로세스에 의해 사용 중일 떄

  • 자신이 읽으려는 버퍼에 다른 프로세스가 쓰기 작업을 진행 중이라면 선행 프로세스가 일을 마칠 때까지 기다려야 한다.
  • buffer busy waits, latch free, enqueue 관련 대기 이벤트

2. 다른 프로세스에 의해 선행작업이 완료되기를 기다릴 때 :

  • Dirty 버퍼를 디스크에 기록할 때는 먼저 LGWR가 로그 버퍼에 있는 Redo entry 따라서 DBWR는 LGWR를 깨워 로그 버퍼를 비우라는 신호를 보내고
    LGWR를 깨우고 자신은 대기 상태로 빠진다.
  • write complete waits, checkpoing completed, log file sync, log file switch 이벤트 등이 여기에 속한다.

할 일이 없을 때( -> idle 대기 이벤트 )

  • 서버 프로세스는 쿼리 결과를 사용자에게 전송하는 동안 Array 단위로 일을 처리하는데, Array 크기만큼 데이터를 전송하면 다음 Fetch Call을 받을 때까지 기다린다.
    쿼리 결과집합을 모두 전송하고 나서도 다음 Parse Call또는 Execute Call을 받을 때가지 기다린다.
  • 병렬 쿼리를 수행하면 자신이 맡은 일을 먼저 끝마지치는 병렬 Slave 프로세스가 생기는데 그럴 때면 다른 Slave들이 마칠 때까지 대기 상태에서 기다린다.
  • SQL*NET message from client, PX Deq:Execution Msg 등이 여기에 속한다.

(3) 대기 이벤트는 언제 사라질까?

  • 1. 대기 상태에 빠진 프로세스가 기다리던 리소스가 사용 가능해 지거나
  • 2. 작업을 계속 진행하기 위한 성행작업이 완료되거나
  • 3. 해야 할 일이 생겼을 때

(4) 래치와 대기 이벤트 개념 명확화

래치?

  • 래치를 얻는 과정 자체가 경합을 의미하지는 않는다. 공유된 자원을 읽으려면 래치를 얻는 것이 당연한 일이므로 v$latch뷰에서 gets 횟수가 증가한다고 해서 문제될 것은 없다.
    그저 공유자원에 대한 접근 요청이 많았던 것으로 이해하면 된다.
    다만, 그 과정에서 다른 프로세스와 경합이 발생하는지를 관심 있게 살펴봐야 하며, 만약 그렇다면 시스템의 동시성이 저하되므로 문제다.

v$latch

  • gets : 래치 요청횟수를 말한다. ( gets - misses = 성공한 횟수( simple_gets ) )
  • misses : 래치를 요청했는데 다른 프로세스에 의해 자원이 사용 중이어서 첫 번째시도에서 곧바로 래치를 얻지 못하는 횟수다.
    래치 miss를 만나 프로세스는, 이후 spin 과정에서 래치 획득에 성공하거나 정해진 횟수만큼의 spin 후에도 래치획득에 실패해 대기 상태에 들어가는, 둘 중 하나의 길을 걷게 된다.
  • sping_gets: 래치를 요청한 첫 번째 시도에서 곧바로 래치를 얻지는 못했지만 이후 sping하는 과정에서 래치 획득에 성공한 횟수 ( misses - sleeps = sping_gets )
    즉, 첫 번째 시도에서 래치를 얻지는 못했지만 다행히 Sleep전에 래치를 얻게 되는 경우다.
  • sleeps : 정해진 횟수( _sping_count = 2000 ) 만큼 계속 spin 했는데도 결국 래치를 얻지 못해 대기 상태로 빠진 횟수다. 이때 발생하는 것이 latch free 대기 이벤트다.
    latch: cache buffers chains, latch: library cache lock