My Books

My Slides

rss 아이콘 이미지

1. 테스트 개요


2번 노드에서 레코드 1건 (마스터 노드: 3번)을 변경한 후에 1번 및 3번 노드에서 동일 레코드를 각각 7번 조회합니다. 이를 통해 변경 중인 블록을 조회할 때 발생하는 대기이벤트와 성능 지표를 살펴보고 버퍼 캐시 및 GRD의 변경 내용을 확인합니다. 그리고 _db_block_max_cr_dba 파라미터의 동작원리 또한 파악하도록 합니다.



2. 2번 노드에서 1건 UPDATE


2번 노드에서 1건을 변경하면 해당 블록에 대한 XCUR 버퍼 및 CR 버퍼가 캐시에 적재됩니다. (그림-1 참조) 이때 발생하는 변경 사항은 아래의 테스트 결과 중간중간에 주석으로 설명해 두었습니다. (테스트 수행 전에 버퍼 캐시를 flush합니다)


그림-1. 2번 노드에서 1건 변경 후의 버퍼 캐시 변경 내용


-- 해당 블록은 로컬 및 리모트 캐시에 존재하지 않으므로 3번 노드의 LMS로부터 블록 액세스 권한을 부여 받습니다.
-- 이로 인해 'gc cr grant 2-way' 대기이벤트가 1회 발생합니다. 

-- 그런 후에, 싱글 블록 IO를 이용해서 해당 블록(File#=6, Block#=228)을 메모리로 적재합니다. 
-- 이때 'db file sequential read' 대기이벤트가 1회 발생합니다.

-- 해당 블록을 적재한 후에는 해당 블록을 변경하기 위한 CURRENT 권한을 부여 받아야합니다.
-- 이로 인해 'gc current grant 2-way' 대기이벤트가 1회 발생합니다.

-- 또한, 변경 작업을 위한 언두 블록을 할당 받기 위해 'db file sequential read' 대기이벤트가 2회 발생합니다.
-- 블록 덤프를 수행해보면 각각 언두 헤더 블록과 언두 블록임을 알 수 있습니다. 
 
SCOTT@OOW2:2> @set_trace_on 10046 8
SCOTT@OOW2:2> @one_row_update 

WAIT #140225505518032: nam='gc cr grant 2-way' ela= 1913 p1=6 p2=228 p3=1 obj#=93823 tim=294714258816
WAIT #140225505518032: nam='db file sequential read' ela= 1918 file#=6 block#=228 blocks=1 obj#=93823 tim=294714261240
WAIT #140225505518032: nam='gc current grant 2-way' ela= 2213 p1=6 p2=228 p3=33619969 obj#=93823 tim=294714263898
WAIT #140225505518032: nam='db file sequential read' ela= 2029 file#=5 block#=144 blocks=1 obj#=0 tim=294714268613
WAIT #140225505518032: nam='db file sequential read' ela= 1150 file#=5 block#=1796 blocks=1 obj#=0 tim=294714270377
 
SYS@OOW2:2> alter system dump datafile 5 block 144;
frmt: 0x02 chkval: 0xbae3 type: 0x26=KTU SMU HEADER BLOCK 

SYS@OOW2:2> alter system dump datafile 5 block 1796;
frmt: 0x02 chkval: 0xfdae type: 0x02=KTU UNDO BLOCK 

-- V$SESSTAT 뷰의 변경 사항 (참고만 하세요)

SYS@OOW1:1> @init_temp_sesstat 91 65 43
SYS@OOW1:1> @get_temp_sesstat  91 65 43

INST_ID SERVER FLAG     NAME                           VALUE
------- ------ -------- ------------------------------ -----
      2 [FG]   [EVENT]  db file sequential read            3
                        gc cr grant 2-way                  1
                        gc current grant 2-way             1						
               [STAT]   physical reads                     3
                        session logical reads              4

-- 2번 노드에 XCUR 버퍼 1개와 CR 버퍼 1개가 적재되었습니다.
-- 그리고 2번 노드의 GRD에 GCS 클라이언트 (락 엘리먼트 존재)가 1개 생성되고 
-- 마스터 노드인 3번 노드에 GCS SHADOW가 1개 생성되었습니다. 
 						
SYS@OOW1:1> @fnd_gcs_detail2 6 228

                        X$BH X$BH   X$BH                   X$BH
INST ADDR              CLASS STATE  LE_ADDR                 TCH BA
---- ---------------- ------ ------ ---------------- ---------- ----------------
OOW2 00007F79DD4C4F08      1 CR     00                        0 00000000734C2000
     00007F79DD4C5088      1 XCUR   00000000733E2EB0          2 000000007513A000

     X$KJBL           X$KJBL X$KJBL    X$KJBL     X$BH               X$BH X$BH
INST LOCKP             OWNER GRANT     LOCKST     LE_ADDR           CLASS STATE
---- ---------------- ------ --------- ---------- ---------------- ------ ------
OOW2 00000000733E2F38      1 KJUSEREX  GRANTED    00000000733E2EB0      1 XCUR
OOW3 00000000696D70C8      1 KJUSEREX  GRANTED



3. 1번 노드에서 해당 레코드 조회 (1회 수행)


1번 노드에서 동일한 레코드를 조회하면 1번 노드 및 2번 노드에 해당 블록에 대한 CR 버퍼가 버퍼 캐시에 적재됩니다. (그림-2 참조)


그림-2. 1번 노드에서 1건 조회 후의 버퍼 캐시 변경 내용


-- 해당 블록은 현재 변경 전 (COMMIT 전이므로 'busy'상태)입니다.
-- 따라서 'gc cr block busy' 대기이벤트가 1회 발생합니다. 

SCOTT@OOW1:1> @set_trace_on 10046 8
SCOTT@OOW1:1> @one_row_select 

WAIT #139902907847544: nam='gc cr block busy' ela= 18363 p1=6 p2=228 p3=1 obj#=93823 tim=311836140232

SYS@OOW1:1> @init_temp_sesstat 91 65 43
SYS@OOW1:1> @get_temp_sesstat  91 65 43

-- 1번 노드의 Foreground 프로세스는 CR 버퍼를 1개 전송 받았음을 알 수 있습니다.
-- 2번 노드의 LMS는 CR 버퍼를 1개 생성한 후에 1번 노드로 해당 버퍼를 전송한 것을 알 수 있습니다. 

INST_ID SERVER FLAG     NAME                           VALUE
------- ------ -------- ------------------------------ -----
      1 [FG]   [EVENT]  gc cr block busy                   1
               [STAT]   gc cr blocks received              1
                        session logical reads              1
      2 [LMS]  [STAT]   CR blocks created                  1
                        gc cr blocks flushed               1
                        gc cr blocks served                1
                        session logical reads              3

-- 1번 노드와 2번 노드에 CR 버퍼가 각각 1개씩 더 적재되었습니다. 
						
SYS@OOW1:1> @fnd_gcs_detail2 6 228

                        X$BH X$BH   X$BH                   X$BH
INST ADDR              CLASS STATE  LE_ADDR                 TCH BA
---- ---------------- ------ ------ ---------------- ---------- ----------------
OOW1 00007F8072037AC8      1 CR     00                        1 0000000074298000

OOW2 00007F79DD69C000      1 CR     00                        0 00000000734C2000
     00007F79DD69C180      1 XCUR   00000000733E2EB0          2 000000007513A000
     00007F79DD69C300      1 CR     00                        0 000000007545E000

     X$KJBL           X$KJBL X$KJBL    X$KJBL     X$BH               X$BH X$BH
INST LOCKP             OWNER GRANT     LOCKST     LE_ADDR           CLASS STATE
---- ---------------- ------ --------- ---------- ---------------- ------ ------
OOW2 00000000733E2F38      1 KJUSEREX  GRANTED    00000000733E2EB0      1 XCUR
OOW3 00000000696D70C8      1 KJUSEREX  GRANTED



4. 1번 노드에서 해당 레코드 조회 (6회 수행)


해당 레코드를 6회 반복해서 조회하면 1, 2번 모두 6개의 CR 버퍼가 적재됩니다. (그림-3 참조) 즉, 'busy'한 블록을 반복적으로 조회하면 조회할 때마다 CR 버퍼가 적재되고, 최대 값은 _db_block_max_cr_dba 파라미터에 의해 결정됩니다. 해당 파라미터의 기본 설정 값은 6이므로 최대 6개의 CR 버퍼가 적재된 것을 알 수 있습니다.


그림-3. 1번 노드에서 6번 조회 후의 버퍼 캐시 변경 내용



-- 해당 블록은 현재 변경 전 (COMMIT 전이므로 'busy'상태)입니다.
-- 따라서 'gc cr block busy' 대기이벤트가 1회 발생합니다. 
 
SCOTT@OOW1:1> @set_trace_on 10046 8
SCOTT@OOW1:1> @one_row_select 

WAIT #139902907847544: nam='gc cr block busy' ela= 4052 p1=6 p2=228 p3=1 obj#=93823 tim=311885751211

-- 이전과 동일하게 2번 노드의 LMS는 CR 버퍼를 1개 생성한 후 1번 노드로 전송한 것을 알 수 있습니다.

SYS@OOW1:1> @init_temp_sesstat 91 65 43
SYS@OOW1:1> @get_temp_sesstat  91 65 43

INST_ID SERVER FLAG     NAME                           VALUE
------- ------ -------- ------------------------------ -----
      1 [FG]   [EVENT]  gc cr block busy                   1
               [STAT]   gc cr blocks received              1
                        session logical reads              1
      2 [LMS]  [STAT]   CR blocks created                  1
                        gc cr blocks flushed               1
                        gc cr blocks served                1
                        session logical reads              3

-- 1,2번 노드 각각 6개의 CR 버퍼가 적재되었습니다. 
						
SYS@OOW1:1> @fnd_gcs_detail2 6 228

                        X$BH X$BH   X$BH                   X$BH
INST ADDR              CLASS STATE  LE_ADDR                 TCH BA
---- ---------------- ------ ------ ---------------- ---------- ----------------
OOW1 00007F80720374A8      1 CR     00                        1 0000000073D70000
     00007F8072037648      1 CR     00                        1 0000000074034000
     00007F80720377C8      1 CR     00                        1 0000000074274000
     00007F8072037948      1 CR     00                        1 0000000074CD0000
     00007F8072037AC8      1 CR     00                        1 00000000739E8000
     00007F807236C5A0      1 CR     00                        1 0000000074298000

OOW2 00007F79DD69BA00      1 XCUR   00000000733E2EB0          2 000000007513A000
     00007F79DD69BB80      1 CR     00                        0 000000007545E000
     00007F79DD69BD00      1 CR     00                        0 0000000075772000
     00007F79DD69BE80      1 CR     00                        0 0000000072EB4000
     00007F79DD69C000      1 CR     00                        0 0000000075038000
     00007F79DD69C180      1 CR     00                        0 00000000734C2000
     00007F79DD69C300      1 CR     00                        0 0000000073194000

     X$KJBL           X$KJBL X$KJBL    X$KJBL     X$BH               X$BH X$BH
INST LOCKP             OWNER GRANT     LOCKST     LE_ADDR           CLASS STATE
---- ---------------- ------ --------- ---------- ---------------- ------ ------
OOW2 00000000733E2F38      1 KJUSEREX  GRANTED    00000000733E2EB0      1 XCUR
OOW3 00000000696D70C8      1 KJUSEREX  GRANTED



5. 1번 노드에서 해당 레코드 조회 (7회 수행)


그렇다면, 해당 레코드를 7번쨰 조회할 경우에는 어떤 변화가 발생하는지 확인해보겠습니다.

-- 여전히, 'gc cr block busy' 대기이벤트가 발생합니다. 

SCOTT@OOW1:1> @set_trace_on 10046 8
SCOTT@OOW1:1> @one_row_select

WAIT #139902907847544: nam='gc cr block busy' ela= 7971 p1=6 p2=228 p3=1 obj#=93823 tim=311953030887

-- 여전히, 2번 노드의 LMS는 CR 버퍼를 1개 생성한 후 1번 노드로 전송합니다. 
-- 이를 통해, _db_block_max_cr_dba 파라미터는 CR 버퍼의 생성과 관련된 것이 아니라
-- CR 버퍼의 적재 개수와 관련된 것임을 알 수 있습니다.

SYS@OOW1:1> @init_temp_sesstat 91 65 43
SYS@OOW1:1> @get_temp_sesstat  91 65 43

INST_ID SERVER FLAG     NAME                           VALUE
------- ------ -------- ------------------------------ -----
      1 [FG]   [EVENT]  gc cr block busy                   1
               [STAT]   gc cr blocks received              1
                        session logical reads              1
      2 [LMS]  [STAT]   CR blocks created                  1
                        gc cr blocks flushed               1
                        gc cr blocks served                1
                        session logical reads              3

-- 버퍼 캐시내의 큰 변화는 없습니다. 즉, 여전히 CR 버퍼의 개수는 6개입니다.
-- 다만, 새로운 CR 버퍼가 1개 적재되었고 기존의 CR 버퍼 1개는 aged out 되었음을 알 수 있습니다. 			
			
SYS@OOW1:1> @fnd_gcs_detail2 6 228

                        X$BH X$BH   X$BH                   X$BH
INST ADDR              CLASS STATE  LE_ADDR                 TCH BA
---- ---------------- ------ ------ ---------------- ---------- ----------------
OOW1 00007F80728A21E8      1 CR     00                        1 0000000074034000
     00007F8072A48158      1 CR     00                        1 0000000074274000
     00007F8072A482F8      1 CR     00                        1 0000000074CD0000
     00007F8072A48478      1 CR     00                        1 00000000739E8000
     00007F8072A485F8      1 CR     00                        1 0000000074298000
     00007F8072A48778      1 CR     00                        1 0000000073D70000

OOW2 00007F79DD4C4788      1 XCUR   00000000733E2EB0          2 000000007513A000
     00007F79DD4C4908      1 CR     00                        0 0000000072EB4000
     00007F79DD4C4A88      1 CR     00                        0 0000000075038000
     00007F79DD4C4C08      1 CR     00                        0 00000000734C2000
     00007F79DD4C4D88      1 CR     00                        0 0000000073194000
     00007F79DD4C4F08      1 CR     00                        0 000000007545E000
     00007F79DD4C5088      1 CR     00                        0 0000000075772000

     X$KJBL           X$KJBL X$KJBL    X$KJBL     X$BH               X$BH X$BH
INST LOCKP             OWNER GRANT     LOCKST     LE_ADDR           CLASS STATE
---- ---------------- ------ --------- ---------- ---------------- ------ ------
OOW2 00000000733E2F38      1 KJUSEREX  GRANTED    00000000733E2EB0      1 XCUR
OOW3 00000000696D70C8      1 KJUSEREX  GRANTED

3번 노드에서 동일한 테스트를 수행한 결과, GCS SHADOW가 생성되지 않다는 점을 제외하면 1번 노드의 테스트 결과와 동일합니다. 따라서 설명은 생략합니다. 


이전: [캐시 퓨전 #1] SELECT 시에 발생하는 gc cr grant 2-way 대기이벤트에 대한 이해
다음: [캐시 퓨전 #3] 커밋된 블록 SELECT 시에 발생하는 gc cr/current block 2-way, 3-way 대기이벤트 및 _fairness_threshold 파라미터에 대한 이해



 

저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

이번 시간에 살펴볼 내용은 캐시 퓨전 시에 발생하는 클러스터 관련 대기이벤트들 및 이와 연관된 성능 지표들의 변경사항, 그리고 버퍼 캐시 내의 버퍼 상태 및 GRD의 변경 사항들입니다. 테스트를 위해 10046 트레이스, V$SESSTAT, X$BH, X$KJBL Fixed 테이블을 이용했습니다. 연재 순서는 다음과 같습니다.


[캐시 퓨전 #1] SELECT 시에 발생하는 gc cr grant 2-way 대기이벤트에 대한 이해


테스트 환경 : Oracle 12.1.0.2 (64bits) 3 노드 RAC


1. 테스트 개요


2번 노드에서 레코드 1건 (마스터노드: 3번)을 조회한 후에 1번 및 3번 노드에서 동일 레코드를 각각 조회합니다. 테스트의 편의성을 위해 인덱스를 생성하지 않고 해당 레코드의 ROWID를 이용해서 조회하며, 조회 시에 발생하는 대기이벤트와 성능지표를 살펴보고 버퍼 캐시 및 GRD의 변경 내용을 확인합니다.



2. 초기 환경 SETUP


-- 테스트 테이블 생성 및 데이터 입력

SCOTT@OOW1:1> drop table t1 purge;
SCOTT@OOW1:1> create table t1 (c1 number, c2 number);
SCOTT@OOW1:1> insert into t1 select level, level from dual connect by level<=10000;
SCOTT@OOW1:1> commit;
SCOTT@OOW1:1> exec dbms_stats.gather_table_stats(user,'T1');

--C1=1에 대한 블록 마스터 노드가 OOW3 (KJBRMASTER=2)임을 확인

SCOTT@OOW1:1> @fnd_blk_master T1 1

        C1     OBJ_NO    FILE_NO     BLK_NO
---------- ---------- ---------- ----------
         1      93823          6        228

       X$BH X$KJBR                                                       X$KJBR
INST  CLASS NAME                           KJBLNAME2       KJBRGRANT     MASTER
---- ------ ------------------------------ --------------- --------- ----------
OOW3      1 [0xe4][0x6],[BL][ext 0x0,0x0]  228,6,BL        KJUSEREX           2

-- 모든 노드에서 buffer cache flush 수행 

SYS@OOW1:1> alter system flush buffer_cache;
SYS@OOW2:2> alter system flush buffer_cache;
SYS@OOW3:3> alter system flush buffer_cache;



3. 2번 노드에서 1건 조회


2번 노드에서 1건을 조회하면 해당 블록에 대한 SCUR 버퍼가 버퍼 캐시에 적재됩니다. (그림-1 참조) 이때 발생하는 변경 사항은 아래의 테스트 결과 중간중간에 주석으로 설명해 두었습니다.


그림-1. 2번 노드에서 1건 조회 후의 버퍼 캐시 변경 내용


-- 해당 블록은 로컬 및 리모트 버퍼 캐시에 존재하지 않으므로 3번 노드의 LMS로부터 블록 액세스 권한을 부여 받습니다. 
-- 이로 인해 'gc cr grant 2-way' 대기이벤트가 1회 발생합니다. 
-- 그런 후에, 싱글 블록 IO를 이용해서 해당 블록(File#=6, Block#=228)을 메모리로 적재합니다. 
-- 이때 'db file sequential read' 대기이벤트가 1회 발생합니다.
 
SCOTT@OOW2:2> @set_trace_on 10046 8
SCOTT@OOW2:2> @one_row_select 

WAIT #140225505500112: nam='gc cr grant 2-way' ela= 1991 p1=6 p2=228 p3=1 obj#=93696 tim=282496042645
WAIT #140225505500112: nam='db file sequential read' ela= 4141 file#=6 block#=228 blocks=1 obj#=93696 tim=282496046954

-- 10046 트레이스에서 확인한 것과 동일한 대기이벤트 정보를 확인할 수 있습니다. 
-- 더불어 DISK IO 1회, 메모리 IO 1회가 발생한 것을 알 수 있습니다.

SYS@OOW1:1> @init_temp_sesstat 91 65 43
SYS@OOW1:1> @get_temp_sesstat  91 65 43

INST_ID SERVER FLAG     NAME                           VALUE
------- ------ -------- ------------------------------ -----
      2 [FG]   [EVENT]  db file sequential read            1
                        gc cr grant 2-way                  1
               [STAT]   physical reads                     1
                        session logical reads              1

-- 2번 노드에 SCUR 버퍼가 1개 적재되었습니다. 
-- 그리고 2번 노드의 GRD에 GCS 클라이언트 (락 엘리먼트 존재)가 1개 생성되고 
-- 마스터 노드인 3번 노드에 GCS SHADOW가 1개 생성되었습니다. 
				
SYS@OOW1:1> @fnd_gcs_detail2 6 228

                        X$BH X$BH   X$BH                   X$BH
INST ADDR              CLASS STATE  LE_ADDR                 TCH BA
---- ---------------- ------ ------ ---------------- ---------- ----------------
OOW2 00007F79DD4F7A60      1 SCUR   00000000733E2EB0          1 00000000738EC000

     X$KJBL           X$KJBL X$KJBL    X$KJBL     X$BH               X$BH X$BH
INST LOCKP             OWNER GRANT     LOCKST     LE_ADDR           CLASS STATE
---- ---------------- ------ --------- ---------- ---------------- ------ ------
OOW2 00000000733E2F38      1 KJUSERPR  GRANTED    00000000733E2EB0      1 SCUR
OOW3 00000000696EB438      1 KJUSERPR  GRANTED



4. 2번 노드에서 1번 더 조회


2번 노드에서 동일한 레코드를 1번 더 조회할 경우에는 로컬 캐시에서 해당 블록을 읽게 됩니다. 따라서 클러스터 및 IO 관련 대기이벤트 및 GRD 내의 변경은 발생하지 않습니다. 로컬 캐시에서 원하는 블록을 읽었으므로 메모리 IO가 1회 증가하고 해당 버퍼의 TCH가 2로 증가하는 정도의 변경만 발생합니다.


-- 클러스터 및 IO 관련 대기이벤트는 발생하지 않습니다.

SCOTT@OOW2:2> @set_trace_on 10046 8
SCOTT@OOW2:2> @one_row_select 

-- 해당 버퍼에 대한 메모리 IO가 1회 발생합니다. 

SYS@OOW1:1> @init_temp_sesstat 91 65 43
SYS@OOW1:1> @get_temp_sesstat  91 65 43

INST_ID SERVER FLAG     NAME                           VALUE
------- ------ -------- ------------------------------ -----
      2 [FG]   [STAT]   session logical reads              1

-- 해당 버퍼에 대한 액세스로 인해 TCH가 2로 증가합니다.
	  
SYS@OOW1:1> @fnd_gcs_detail 6 228

                        X$BH X$BH   X$BH                   X$BH
INST ADDR              CLASS STATE  LE_ADDR                 TCH BA
---- ---------------- ------ ------ ---------------- ---------- ----------------
OOW2 00007F79DD4FAC58      1 SCUR   00000000733E2EB0          2 0000000073922000

     X$KJBL           X$KJBL X$KJBL    X$KJBL     X$BH               X$BH X$BH
INST LOCKP             OWNER GRANT     LOCKST     LE_ADDR           CLASS STATE
---- ---------------- ------ --------- ---------- ---------------- ------ ------
OOW2 00000000733E2F38      1 KJUSERPR  GRANTED    00000000733E2EB0      1 SCUR
OOW3 00000000696D44B8      1 KJUSERPR  GRANTED

5. 1번 노드에서 조회


1번 노드에서 동일한 레코드를 조회하면 해당 블록에 대한 SCUR 버퍼가 버퍼 캐시에 적재됩니다. (그림-2 참조) 캐시 퓨전을 설명한 문서들을 보면 이러한 경우에는 해당 블록은 캐시 퓨전을 통해서 리모트 캐시(2번 노드)에서 전송 받고, 이로 인해 'gc current block 2/3 way' 대기이벤트가 발생하는 것으로 되어있습니다만, 테스트 결과는 조금 다릅니다. 이러한 차이는 테스트 환경 (버전 또는 buffer cache flush 여부 등)의 차이라고 보여집니다.


그림-2. 1번 노드에서 1건 조회 후의 버퍼 캐시 변경 내용


-- 2번 노드와 동일한 결과를 나타냅니다. 

SCOTT@OOW1:1> @set_trace_on 10046 8
SCOTT@OOW1:1> @one_row_select 

WAIT #139902827437888: nam='gc cr grant 2-way' ela= 4187 p1=6 p2=228 p3=1 obj#=93696 tim=309078519225
WAIT #139902827437888: nam='db file sequential read' ela= 6589 file#=6 block#=228 blocks=1 obj#=93696 tim=309078528563

-- V$SESSTAT 뷰의 변경 사항 (참고만 하세요) 

SYS@OOW1:1> @init_temp_sesstat 91 65 43
SYS@OOW1:1> @get_temp_sesstat  91 65 43

INST_ID SERVER FLAG     NAME                           VALUE
------- ------ -------- ------------------------------ -----
      1 [FG]   [EVENT]  db file sequential read            1
                        gc cr grant 2-way                  1
               [STAT]   physical reads                     1
                        session logical reads              1

-- 1번 노드에 SCUR 버퍼가 1개 적재되었습니다. 
-- 그리고 2번 노드의 GRD에 GCS 클라이언트가 1개 생성되고, 
-- 마스터 노드인 3번 노드에 GCS SHADOW가 1개 생성되었습니다.
 						
SYS@OOW1:1> @fnd_gcs_detail2 6 228

                        X$BH X$BH   X$BH                   X$BH
INST ADDR              CLASS STATE  LE_ADDR                 TCH BA
---- ---------------- ------ ------ ---------------- ---------- ----------------
OOW1 00007F80726712D0      1 SCUR   00000000747F19D8          1 00000000750EE000
OOW2 00007F79E2242F58      1 SCUR   00000000733E2EB0          0 0000000074940000

     X$KJBL           X$KJBL X$KJBL    X$KJBL     X$BH               X$BH X$BH
INST LOCKP             OWNER GRANT     LOCKST     LE_ADDR           CLASS STATE
---- ---------------- ------ --------- ---------- ---------------- ------ ------
OOW1 00000000747F1A60      0 KJUSERPR  GRANTED    00000000747F19D8      1 SCUR
OOW2 00000000733E2F38      1 KJUSERPR  GRANTED    00000000733E2EB0      1 SCUR
OOW3 00000000697216F0      1 KJUSERPR  GRANTED
OOW3 00000000696CDD20      0 KJUSERPR  GRANTED


6. 3번 노드에서 조회


3번 노드에서 동일한 레코드를 조회하면 해당 블록에 대한 SCUR 버퍼가 버퍼 캐시에 적재됩니다. (그림-3 참조)


그림-3. 3번 노드에서 1건 조회 후의 버퍼 캐시 변경 내용


-- 3번 노드가 마스터 노드이므로 GRANT 수행 없이 싱글 블록 IO를 이용해서 버퍼에 적재합니다.
-- 따라서 'gc cr grant 2-way' 대기 없이 'db file sequential' 대기이벤트만 1회 발생합니다.

SCOTT@OOW3:3> @set_trace_on 10046 8
SCOTT@OOW3:3> @one_row_select 

WAIT #140357040867896: nam='db file sequential read' ela= 4382 file#=6 block#=228 blocks=1 obj#=93696 tim=282758433936

-- V$SESSTAT 뷰의 변경 사항 (참고만 하세요) 

SYS@OOW1:1> @init_temp_sesstat 91 65 43
SYS@OOW1:1> @get_temp_sesstat  91 65 43

INST_ID SERVER FLAG     NAME                           VALUE
------- ------ -------- ------------------------------ -----
      3 [FG]   [EVENT]  db file sequential read            1
               [STAT]   physical reads                     1
                        session logical reads              1						

-- 3번 노드에 SCUR 버퍼가 1개 적재되었습니다. 
-- 3번 노드가 마스터 노드이므로 GCS SHADOW는 생성되지 않고 GCS 클라이언트만 1개 생성되었습니다. 
						
SYS@OOW1:1> @fnd_gcs_detail2 6 228

                        X$BH X$BH   X$BH                   X$BH
INST ADDR              CLASS STATE  LE_ADDR                 TCH BA
---- ---------------- ------ ------ ---------------- ---------- ----------------
OOW1 00007F8072671870      1 SCUR   00000000747F19D8          1 0000000075744000
OOW2 00007F79DD4C9298      1 SCUR   00000000733E2EB0          1 0000000073418000
OOW3 00007FBB31F831B0      1 SCUR   00000000757DC498          1 0000000072E32000

     X$KJBL           X$KJBL X$KJBL    X$KJBL     X$BH               X$BH X$BH
INST LOCKP             OWNER GRANT     LOCKST     LE_ADDR           CLASS STATE
---- ---------------- ------ --------- ---------- ---------------- ------ ------
OOW1 00000000747F1A60      0 KJUSERPR  GRANTED    00000000747F19D8      1 SCUR
OOW2 00000000733E2F38      1 KJUSERPR  GRANTED    00000000733E2EB0      1 SCUR
OOW3 0000000069715DC8      1 KJUSERPR  GRANTED
OOW3 00000000697273C0      0 KJUSERPR  GRANTED
OOW3 00000000757DC520      2 KJUSERPR  GRANTED    00000000757DC498      1 SCUR


다음: [캐시 퓨전 #2] 변경중인 블록 SELECT 시에 발생하는 gc cr block busy 대기이벤트 및 _db_block_max_cr_dba 파라미터에 대한 이해

저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

일반적으로 노드 별로 스키마를 분리해서 운영하는 환경 (또는 인스턴스별로 업무가 나뉜 환경)에서는 블록 마스터 노드가 분산되더라도 성능 상의 문제는 거의 없습니다. (여기서 "거의"라고 하는 부분은 초기 디스크 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의 필요성에 대한 설명 바로가기

저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License


 

티스토리 툴바