[19] 블록 마스터 노드 분산에 따른 gc cr grant 2-way 문제 가능성 및 해결 방안

일반적으로 노드 별로 스키마를 분리해서 운영하는 환경 (또는 인스턴스별로 업무가 나뉜 환경)에서는 블록 마스터 노드가 분산되더라도 성능 상의 문제는 거의 없습니다. (여기서 “거의”라고 하는 부분은 초기 디스크 IO시에 GC GRANT 메시지를 전송 받는데 필요한 몇 밀리세컨 정도의 미미한 부하) 즉, 초기 1회의 디스크 IO를 제외하면, 이후의 메모리 IO는 모두 로컬 노드에서 수행되므로 성능 이슈는 없다고 할 수 있습니다. 하지만, 아주 운이 없는 경우, 초기 1회의 디스크 IO를 위해 GC GRANT 메세지를 전송 받는 시점에(해당 블록의 마스터 노드가 리모트인 경우), 리모트 노드의 LMS의 부하로 인해 메시지 전송이 지연된다면 gc cr grant 2-way  대기이벤트의 대기 시간이 길어지는 문제가 발생하며, 이로 인해 장애가 유발될 가능성도 배제할 수 없습니다. 이번 시간에는 이러한 문제 가능성에 대해서 테스트를 통해 검증해보고, 수동 DRM을 통해 문제를 해결하는 방안을 설명합니다.

1) 1개 로우의 마스터 노드 확인


테스트를 위해 1개 로우가 저장된 블록의 마스터 노드를 확인합니다. 확인 결과, C1=129 로우의 마스터 노드는 OOW2임을 알 수 있습니다. (참고로 KJMRMASTER 칼럼 값은 0부터 시작합니다. 따라서 1인 경우에는 2번 노드인 OOW2가 마스터 노드가 됩니다)

SCOTT @ OOW1 >  @fnd_blk_master T1 129

C1     OBJ_NO    FILE_NO     BLK_NO
---------- ---------- ---------- ----------
129      93205          8        275

INST      CLASS KJBRNAME                       KJBLNAME2       KJBRGRANT KJBRMASTER
---- ---------- ------------------------------ --------------- --------- ----------
OOW2          1 [0x113][0x8],[BL][ext 0x0,0x0] 275,8,BL        KJUSEREX           1

2) 10046 트레이스를 이용한 대기 이벤트 분석


인덱스 및 테이블 블록에 대한 마스터가 모두 리모트 노드이므로 db file sequential read 대기이벤트가 발생하기 전에 gc cr grant 2-way 대기이벤트가 발생하는 것을 확인할 수 있습니다. (대기이벤트에 대한 자세한 설명은 별도 포스팅으로 다룰 예정입니다) 개별 gc cr grant 2-way 대기이벤트의 대기시간은 1~2 밀리세컨 이하이므로 성능 상의 문제는 없다고 볼 수 있습니다. 다만, 디스크 IO가 빈번하게 발생하는 경우에는 그와 비례해서 대기 시간이 증가한다는 점은 간과해서는 안됩니다. 이런 경우에는 4) 항목을 참고해서 수동 리마스터링을 고려할 필요가 있습니다.

SCOTT @ OOW1 > alter system flush buffer_cache;
SCOTT @ OOW1 > @set_trace_on 10046 8
SCOTT @ OOW1 > select /*+ index(t1 t1_idx01) */ c1, dummy from t1 where c1=129;

-- 인덱스 블록 관련 gc 이벤트 2개 발생

WAIT #139730535523040: nam='gc cr grant 2-way' ela= 934 p1=9 p2=131 p3=1 obj#=93206 tim=92098682472
WAIT #139730535523040: nam='db file sequential read' ela= 1657 file#=9 block#=131 blocks=1 obj#=93206 tim=92098684434
WAIT #139730535523040: nam='gc cr grant 2-way' ela= 814 p1=9 p2=177 p3=1 obj#=93206 tim=92098689422
WAIT #139730535523040: nam='db file sequential read' ela= 1209 file#=9 block#=177 blocks=1 obj#=93206 tim=92098691801

-- 테이블 블록 관련 gc 이벤트 1개 발생

WAIT #139730535523040: nam='gc cr grant 2-way' ela= 1238 p1=8 p2=275 p3=1 obj#=93205 tim=92098694278
WAIT #139730535523040: nam='db file sequential read' ela= 1420 file#=8 block#=275 blocks=1 obj#=93205 tim=92098698115

3) LMS Hang 유발 후 동작 방식 확인


블록 마스터 노드인 OOW2 노드의 LMS를 Hang 상태로 만들면 OOW1번에서 해당 블록을 요청하는 세션 역시 Hang 상태에 빠지게 됩니다. (Kill 명령어로 LMS를 stop 시키는 것은 테스트 목적으로 수행한 것이므로 운영 장비에서는 절대 수행해서는 안됩니다. 참고로, 수십 초 이상 LMS를 stop 시킬 경우 인스턴스가 Down되므로 테스트 시에 참고하기 바랍니다) 테스트의 편의성을 위해서 LMS을 stop 시켰으나, 이와 유사하게 리모트 노드의 LMS가 매우 바쁜 상황에서도 이러한 지연이 발생할 가능성이 있다고 이해하시면 좋을 것 같습니다.

-- LMS Hang 유발
SCOTT @ OOW2 > host ps -ef | grep lms | grep OOW2 | grep -v grep
 oracle    2330     1  0 20:39 ?        00:01:08 ora_lms0_OOW2
 SCOTT @ OOW2 > host kill -stop 2330

-- Hang 유발 후 1번 노드에서 조회
SCOTT @ OOW1 > select /*+ index(t1 t1_idx01) */ c1, dummy from t1 where c1=129;

-- 대략 10초 이후 LMS Hang 해제
SCOTT @ OOW2 > host kill -cont 2330

-- 1번 노드 세션의 상태 분석 (gc cr grant 2-way 대기이벤트의 대기시간이 10초 이상 소요됨)

WAIT #139730535523040: nam='gc cr grant 2-way' ela= 11144860 p1=9 p2=131 p3=1 obj#=93206 tim=92297618736
WAIT #139730535523040: nam='db file sequential read' ela= 1621 file#=9 block#=131 blocks=1 obj#=93206 tim=92297620594
WAIT #139730535523040: nam='gc cr grant 2-way' ela= 2555 p1=9 p2=177 p3=1 obj#=93206 tim=92297624002
WAIT #139730535523040: nam='db file sequential read' ela= 2293 file#=9 block#=177 blocks=1 obj#=93206 tim=92297626538
WAIT #139730535523040: nam='gc cr grant 2-way' ela= 2075 p1=8 p2=275 p3=1 obj#=93205 tim=92297629261
WAIT #139730535523040: nam='db file sequential read' ela= 2188 file#=8 block#=275 blocks=1 obj#=93205 tim=92297631913

4) 수동 리소스 리마스터링을 이용한 gc cr grant 2-way 대기이벤트 제거 방법

노드 별로 스키마를 분리했거나, 노드 별로 작업이 분리된 경우에는 수동 리소스 리마스터링을 이용해서 gc cr grant 2-way 대기이벤트를 제거하는 것이 가능합니다. 아래 내용을 참고하세요.

-- 테이블스페이스 번호 확인

SYS @ OOW1 > select ts#, name from ts$ where name in ('TEST_TS','TEST_IDX01');
TS# NAME
---------- ------------------------------
9 TEST_IDX01
8 TEST_TS

-- 오브젝트 번호 확인

SYS @ OOW1 > select data_object_id, object_name from dba_objects where owner='SCOTT' and object_name like 'T1%';
DATA_OBJECT_ID OBJECT_NAME
-------------- ----------------
93206 T1_IDX01
93205 T1

-- oradebug로 수동 리마스터링 수행

SYS @ OOW1 > oradebug setmypid
SYS @ OOW1 > oradebug lkdebug -m pkey 93205 8
SYS @ OOW1 > oradebug lkdebug -m pkey 93206 9

-- 모든 노드에서 flush 수행

SYS @ OOW1 > alter system flush buffer_cache;
SYS @ OOW2 > alter system flush buffer_cache;
SYS @ OOW3 > alter system flush buffer_cache;

SCOTT @ OOW1 > select /*+ index(t1 t1_idx01) */ c1, dummy from t1 where c1=129;

-- gc cr grant 2-way 대기이벤트가 사라진 것을 확인

WAIT #139792444535272: nam='db file sequential read' ela= 9540 file#=9 block#=131 blocks=1 obj#=93206 tim=96291049226
WAIT #139792444535272: nam='db file sequential read' ela= 1279 file#=9 block#=177 blocks=1 obj#=93206 tim=96291050759
WAIT #139792444535272: nam='db file sequential read' ela= 1385 file#=8 block#=275 blocks=1 obj#=93205 tim=96291052617;

이와 같이, 수동 리마스터링을 통해서 GC 관련 대기이벤트를 튜닝하는 방법이 가능합니다. 하지만 _gc_affniti_time (또는 _gc_policy_time)을 0으로 설정해서 DRM을 disable한 경우에는 수동 리마스터링이 수행되지 않는다고 합니다. 따라서 _gc_affniti_time을 0으로 설정하기보다는 _gc_affnity_minimum (또는 _gc_policy_minimum) 값을 아주 높은 값 (수백만)으로 설정해서 DRM은 발생하지 않도록 한 후, 적절히 수동 DRM을 통해 GC 대기이벤트를 튜닝하는 것도 고려해 볼만한 방법입니다.

[20] GCS SHADOW 동작 원리 및 GCS SHADOW의 필요성에 대한 설명 바로가기

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s