Write complete waits

EXEM Knowledge Base

Jump to: navigation, 찾기

목차

[편집] Basic Info

Server Process들이 DBWR 프로세스에 의해 디스크로 기록 중인 블록을 변경하고자 할 경우에는 변경이 끝날 때까지 기다려야 하며, 기다리는 동안 write complete waits 이벤트를 대기한다.

write complete waits 대기는 buffer busy waits 대기와 마찬가지로 buffer lock 경합에 의한 대기로 분류할 수 있다. DBWR은 더티 버퍼를 디스크에 기록하는 동안에 버퍼에 대해 buffer lock을 Exclusive하게 획득한다. 이때 버퍼를 읽거나 변경하려는 다른 프로세스는 이 작업이 끝나기를 기다려야 하고 그동안 write complete waits 이벤트를 대기하게 된다.

write complete waits 대기가 보편적으로 나타나는 경우, 어플리케이션의 문제라기보다는 DBWR의 성능 문제일 가능성이 매우 높다. 서버 프로세스가 디스크에 기록중인 버퍼를 읽을 확률이 실제로는 높지 않은데도, 이로 인한 대기를 겪는다는 것은 DBWR이 더티 버퍼를 기록하는 시간이 지나치게 길다는 것을 의미한다. DBWR의 성능이 느린 이유는 매우 다양하지만 대부분 다음 범주에 들어온다.

[편집] Parameter & Wait Time

[편집] Wait Parameters

write complete waits 이벤트의 대기 파라미터는 다음과 같다.

  • P1 : File#
  • P2 : Block#
  • P3 : Reason ID

[편집] Wait Time

1초

[편집] Check Point & Solution

[편집] 느린 I/O 서브 시스템

free buffer waits#느린 I/O 서브 시스템을 참조한다.

[편집] DBWR의 작업량이 너무 많은 경우

잦은 체크포인트가 발생하는 경우 DBWR의 활동량이 지나치게 많아지고 이로 인해 DBWR의 성능이 저하될 수 있다. DBWR의 성능저하는 시스템의 전체적인 성능저하로 직결된다. FAST_START_MTTR_TARGET 값을 지나치게 작게 주는 경우 빈번하게 증분 체크포인트(Incremental Checkingpoint) 작업이 발생하게 된다. 리두 로그 파일의 크기가 지나치게 작은 경우 잦은 로그 파일 스위치(log file switch)가 발생하게 되고 이로 인해 체크포인트 작업이 늘어난다. Parallel Query로 인해 direct path read가 발생하는 경우, truncate, drop, hot backup시에도 체크포인트가 발생한다. 만일 I/O 시스템의 성능 문제가 없는데도 write complete waits 대기가 나타난다면 DBWR에게 불필요한 부하를 주는 요소가 없는지 살펴볼 필요가 있다.

간접적으로 DBWR의 성능을 개선시키는 방법으로 다중 버퍼 풀(multiple buffer pool)을 적절히 사용하는 것도 권장되고 있다. 시스템에서 일반적으로 자주 사용되는 객체는 Default 버퍼를 사용하고, 그보다는 정도가 낮지만 비교적 주기적으로 사용되는 객체는 Keep 버퍼 풀에 항상 상주시킨다. 마지막으로 사용빈도가 적은 객체는 Recycle 버퍼 풀을 사용한다. Keep 버퍼 풀에 상주된 객체는 상대적으로 디스크에 기록되는 빈도가 낮아지고 이로 인해 write complete waits 대기회수가 줄게 된다. 더불어, Keep 버퍼 풀과 Recycle 버퍼 풀은 각각 별도의 cache buffers lru chain 래치를 사용하기 때문에 래치 경합을 감소시키는 효과도 있다. 다중 버퍼 풀은 DBWR의 성능과는 직접적인 관계는 없지만 버퍼 캐시의 효율성을 높임으로써 메모리에 상주해야 할 데이터가 불필요하게 디스크에 기록되는 빈도를 낮추고, 이로 인해 write complete waits 대기가 발생할 확률을 낮춘다.

오라클 8i 이전에는 write complete waits 대기의 주범으로 write batch size가 꼽혔었다. write batch size가 크면 DBWR이 기록하는 시간이 길어져서 이로 인한 대기가 발생하게 되는데, 8i 이후로는 write batch size에 의한 성능이슈는 사라졌다.

[편집] Event Tip

[편집] FAST_START_MTTR_TARGETwrite complete waits 대기

FAST_START_MTTR_TARGET을 변경하면서 과다한 체크포인트가 write complete waits 대기 및 성능에 어떤 영향을 주는지 테스트해보자. 테스트 시나리오는 다음과 같다.

  • 64,000건의 로우를 갖는 CBL_TEST1 ~ CBL_TEST20 테이블을 생성한다.
  • 동시에 20개의 세션에서 CBL_TEST1 ~ CBL_TEST20 테이블을 각각 업데이트한다.
  • FAST_START_MTTR_TARGET 값을 1로 준 경우와 600으로 준 경우에 시스템 레벨에서 write complete waits 대기가 얼마나 발생하는지 확인한다.
-- 더티 버퍼를 만드는 프로시저
create or replace procedure wcw_update(p_idx in number) is begin for idx in 1 .. 500 loop execute immediate 'update cbl_test'||p_idx || ' set id = id where id = :id' using idx; commit; end loop; end; /
var job_no number;
-- 여러 세션에서 동시에 테이블들을 업데이트 begin for idx in 1 .. 19 loop dbms_job.submit(:job_no, 'wcw_update('||idx||');'); commit; end loop; end; /
exec wcw_update(20);
SQL> select * from ( select event, total_waits, time_waited from v$system_event where wait_class <> 'Idle' order by 3 desc ) where rownum <= 100;

FAST_START_MTTR_TARGET = 1 의 값을 주어서 매우 빈번하게 체크포인트가 발생하도록 한 경우 V$SYSTEM_EVENT를 통해 확인한 대기현상과 V$SYSSTAT를 통해 확인한 체크포인트 관련 통계값은 아래와 같다.

SQL> select * 
from (
select event, total_waits, time_waited 
from v$system_event
where wait_class <> 'Idle'
order by 3 desc
) where rownum <= 100;


EVENT                          TOTAL_WAITS TIME_WAITED
------------------------------ ----------- -----------
log buffer space                      2440       81186
log file switch (private stran         565       31701
d flush incomplete)
free buffer waits                     1367       14198
write complete waits                    56        5334
log file parallel write                524        4964
buffer busy waits                      133        2302
log file switch completion             120        2215
db file sequential read               8589        1761
os thread startup                       47        1759
...

SQL> select name, value from v$sysstat where name like '%checkpoint%;
NAME VALUE -------------------------------------------------- ---------- physical writes non checkpoint 16823 DBWR checkpoint buffers written 18024 DBWR thread checkpoint buffers written 4063 DBWR tablespace checkpoint buffers written 0 DBWR parallel query checkpoint buffers written 0 DBWR checkpoints 7 background checkpoints started 4 background checkpoints completed 3

FAST_START_MTTR_TARGET = 600 의 값을 주어서 체크포인트의 빈도를 줄인 경우 V$SYSTEM_EVENT를 통해 확인한 대기현상과 V$SYSSTAT를 통해 확인한 체크포인트 관련 통계값은 아래와 같다.

SQL> select * 
from (
select event, total_waits, time_waited 
from v$system_event
where wait_class <> 'Idle'
order by 3 desc
) where rownum <= 100;

EVENT TOTAL_WAITS TIME_WAITED ------------------------------ ----------- ----------- log buffer space 2532 77920 free buffer waits 5208 11624 log file switch (checkpoint in 93 6159 complete) log file switch completion 235 5915 log file parallel write 319 4698 os thread startup 46 1658 write complete waits 17 1623 log file sync 41 1554 latch: cache buffers chains 187 1452 ...
SQL> select name, value from v$sysstat where name like '%checkpoint%;
NAME VALUE -------------------------------------------------- ---------- physical writes non checkpoint 9661 DBWR checkpoint buffers written 2089 DBWR thread checkpoint buffers written 1989 DBWR tablespace checkpoint buffers written 0 DBWR parallel query checkpoint buffers written 0 DBWR checkpoints 7 background checkpoints started 4 background checkpoints completed 2

위의 테스트 결과를 보면, FAST_START_MTTR_TARGET = 600으로 주어서 증분 체크포인트의 회수를 줄이면 FAST_START_MTTR_TARGET = 1인 경우에 비해 write complete waits 대기가 크게 줄어들 뿐만 아니라, 그 외 다른 모든 대기현상들도 전반적으로 적게 발생하는 것을 확인할 수 있다. V$SYSSTAT 뷰에서 체크포인트 관련 통계값을 조회해보면 잦은 체크포인트 작업이 대기시간의 차이를 가져왔음을 알 수 있다. 만일 시스템 전체적으로 데이터 변경 작업이 매우 많아서 체크포인트에 의한 부하가 생긴다고 판단되면 증분 체크포인트의 주기를 늘려줌으로써 이 문제를 해결할 수 있다. 하지만, 이 경우 복구(Recovery)에 더 많은 시간이 소요될 수 있다는 점에 유의하자.

[편집] Analysis Case