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

GCS (Glocal Cache Service)와 관련된 인터널 문서를 읽다보면 GCS SHADOW란 용어를 접하게 됩니다. 하지만 GCS SHADOW의 명확한 동작원리에 대해서 언급한 문서를 찾기가 힘듭니다. 그나마 Juian Dyke의 2008년도 PDF 문서에 다음과 같은 정의와 구성도를 확인할 수 있습니다.

“GCS Shadow describes blocks held by other instances, but mastered locally” [Julian Dyke]

그림-1. GCS 메모리 구성도 (참조문헌: Julian Dyke PDF)

20-1

즉, GCS SHADOW란 마스터에 속한 블록을 다른 노드에서 사용할때 이를 표현하는 구조체입니다. (설명이 조금 어렵죠?) 그리고 “그림-1″에서 보여지는 것처럼 GCS SHADOW는 락 엘리먼트를 가지고 있지 않습니다. 그런데 이 설명과 그림만으로는 GCS SHADOW를 정확히 이해하기는 어렵습니다. (적어도 저의 경우는 그랬습니다) 그렇다면 GCS SHADOW는 어떻게 동작하고 어떤 목적으로 사용될까요? 이를 분석하기 위해 테스트를 진행한 결과를 다음과 같이 정리합니다.

1. GCS SHADOW의 동작 원리 및 목적


1-1. GCS SHADOW의 동작 원리

  1. 마스터 노드에서 해당 블록을 액세스할 경우에는 GCS CLIENT가 1개 생성되고 GCS SHADOW는 생성되지 않습니다.
  2. 리모트 노드에서 해당 블록을 액세스할 경우에는 리모트 노드에 GCS CLIENT가 1개 생성되고, 마스터 노드에는 이와 관련된 GCS SHADOW가 1개 생성됩니다. 여러 개의 리모트 노드에서 해당 블록을 액세스한다면 리모트 노드 개수만큼의 GCS SHADOW가 마스터 노드에 생성됩니다.

Note
설명의 편의성을 위해 GCS CLIENT와 GCS SHADOW로 나누었으나, 오라클 내부적으로는 모두 GCS SHADOW로 관리됩니다. GCS CLIENT는 락 엘리먼트가 있는 GCS 구조체 (X$KJBL내에 생성됨)이고 GCS SHADOW는 락 엘리먼트가 없는 GCS 구조체라고 이해하시면 좋습니다. 개인적인 생각이지만 오라클은 용어 및 약어 선정을 아주 잘하는 회사인것 같습니다. GCS SHADOW란 용어도 알고 보면 아주 적절한 용어라고 보입니다. 즉, 그림자와 같이 형체(X$KJBL 구조체)는 동일하지만 알맹이(락 엘리먼트)는 없는 것을 잘 표현하고 있습니다.

그런데 여기서 의문점이 하나 생기게됩니다. “오라클은 이러한 중복 관리를 부하를 감수하면서도 GCS SHADOW를 사용할까?”라는 것이죠. 예를 들어, 마스터 노드의 블록들을 리모트 노드에서 대량으로 액세스하게 되면, 마스터 노드에는 블록 개수만큼의 GCS SHADOW 구조체를 shared pool의 gcs shadow 영역에 생성해야하는 부하가 발생하게 됩니다. 이와 같은 오퍼레이션은 CPU 및 shared pool 사용 측면에서 모두 부하를 유발하게 됩니다. 그렇다면 왜 필요한걸까요?

1-2. GCS SHADOW의 목적
테스트를 통해 추론된 결론은 “GCS SHADOW의 목적은 마스터 노드에 속한 블록들의 사용 노드를 확인하기 위한 것“입니다. 그림-2~그림-4를 보시면 쉽게 이해될것 같습니다.

그림-2. 초기 상태

20-2

그림-3. RAC3 노드에서 UPDATE 수행

20-3

그림-4. RAC2번 노드에서 SELECT 수행

20-4

Note
해당 블록의 마스터 노드는 OOW1이므로 OOW1의 GCS 리소스 구조체를 접근한 후, 해당 구조에 아래 딸린 GCS CLIENT/SHADOW 구조체를 확인합니다. 확인 결과, GCS SHADOW의 정보를 통해 해당 블록은 현재 3번 노드에 있다는 사실을 알 수 있습니다. 이와 같이 GCS SHADOW는 마스터 블록의 사용 노드를 확인하기 위한 용도로 사용된다고 할 수 있습니다.

이러한 결론을 이끌어냈던 테스트 방법에 대해서 자세히 살펴보도록 하겠습니다.

2. GCS SHADOW의 동작원리 분석을 위한 테스트 내역


2-1. 테스트 데이터 생성

SCOTT @ OOW1 > drop table t1 purge;
SCOTT @ OOW1 > create table t1 (c1 number, dummy char(10));
SCOTT @ OOW1 > insert into t1 select level, level from dual connect by level<=10000;
SCOTT @ OOW1 > commit;
SCOTT @ OOW1 > create index t1_idx01 on t1(c1) nologging;
SCOTT @ OOW1 > exec dbms_stats.gather_table_stats(user,'T1');

2-2. 초기 상태 확인

--레코드 1건 조회

SCOTT @ OOW1 > select /*+ index(t1 t1_idx01) */
       count(*),
       max(dbms_rowid.rowid_relative_fno(rowid)) file_no,
       max(dbms_rowid.rowid_block_number(rowid)) blk_no
from   t1
where  c1=1
and    dummy <> '9999';
 
-- 해당 레코드가 속한 블록의 마스터 노드 확인 (마스터 노드가 0번 즉, OOW1번 노드임을 확인)
 
SCOTT @ OOW1 > @fnd_blk_master T1 1
 
        C1     OBJ_NO    FILE_NO     BLK_NO
---------- ---------- ---------- ----------
         1      93240          8        134
 
INST      CLASS KJBRNAME                       KJBLNAME2       KJBRGRANT KJBRMASTER
---- ---------- ------------------------------ --------------- --------- ----------
OOW1          1 [0x86][0x8],[BL][ext 0x0,0x0]  134,8,BL        KJUSEREX           0

2-3. OOW3 노드에서 UPDATE 수행 후의 변경 사항 확인

-- 테스트의 편의성을 위해 모든 노드에서 alter system flush buffer cache 수행 후 3번 노드에서 update 수행

SCOTT @ OOW3 > t1 set c1=-1 where c1=1;

-- 결과 확인
SCOTT @ OOW1 > @fnd_gcs_detail 8 134 
                            
INST ADDR                  CLASS STATE      LE_ADDR                 TCH
---- ---------------- ---------- ---------- ---------------- ----------
OOW3 00007F37A4573068          1 XCUR       0000000072FF5948          1
      
INST RESP                 MASTER NAME
---- ---------------- ---------- ------------------------------
OOW1 000000006946A358          0 [0x86][0x8],[BL][ext 0x0,0x0] 
     
INST LOCKP                 OWNER GRANT     LOCKST     LE_ADDR               CLASS STATE
---- ---------------- ---------- --------- ---------- ---------------- ---------- ----------
OOW1 0000000069722CF8          2 KJUSEREX  GRANTED
OOW3 0000000072FF59D0          2 KJUSEREX  GRANTED    0000000072FF5948          1 XCUR

결과분석
1. 3번 노드에 XCUR 버퍼 1개 할당
2. 해당 블록의 마스터 노드는 0번 (즉, OOW1)임을 재확인
3. 3번 노드에 GCS CLIENT 1개 생성. 그리고 1번 노드에 GCS SHADOW 1개 생성됨

2-4. OOW2 노드에서 SELECT 수행 후의 변경 사항 확인
-- 2번 노드에서 SELECT 수행

SCOTT @ OOW2 > select * from t1 where c1=2;

-- 결과 확인
SCOTT @ OOW1 > @fnd_gcs_detail 8 134 
                          
INST ADDR                  CLASS STATE      LE_ADDR                 TCH
---- ---------------- ---------- ---------- ---------------- ----------
OOW2 00007F6A25D42AD8          1 CR         00                        1
 
OOW3 00007F37A4572EE8          1 XCUR       0000000072FF5948          1
     00007F37A4573068          1 CR         00                        0 
   
INST RESP                 MASTER NAME
---- ---------------- ---------- ------------------------------
OOW1 000000006946A358          0 [0x86][0x8],[BL][ext 0x0,0x0] 
    
INST LOCKP                 OWNER GRANT     LOCKST     LE_ADDR               CLASS STATE
---- ---------------- ---------- --------- ---------- ---------------- ---------- ----------
OOW1 0000000069722CF8          2 KJUSEREX  GRANTED
OOW3 0000000072FF59D0          2 KJUSEREX  GRANTED    0000000072FF5948          1 XCUR

결과분석
1. 3번 노드의 XCUR 버퍼를 1개 복사해서 새로운 XCUR 버퍼 할당. 기존 XCUR 버퍼는 CR 버퍼로 락 다운그레이드됨 (ADDR로 확인)
2. 2번 노드에 CR 버퍼 복사 (3번 노드의 CR 버퍼를 전송받음)
3. CR 버퍼에 대해서는 락 엘리먼트 및 GCS CLIENT 및 SHADOW를 생성하지 않는 것을 확인

스크립트


이 글에 사용된 스크립트는 다음과 같습니다.

fnd_blk_master
fnd_gcs_detail

글을 마치며


설명을 단순화하기 위해서 테스트의 예제를 UPDATE로 했지만, SELECT 및 UPDATE등 다양한 테스트를 한 후 fnd_gcs_detail 스크립트를 이용해서 결과를 분석해보시면 RAC 내부 동작원리를 좀 더 파악할 수 있으리라 생각됩니다. 그리고 이번 포스팅을 끝으로 3개월 동안 진행한 “RAC 동작원리에 대한 연재”를 마무리하려고 합니다. GCS, GES 및 RAC 관련 파라미터에 대한 설명은 연재 내에서 다루기보다는 “성능 분석”이라는 새로운 주제 내에서 다룰 예정입니다. 지금까지는 다소 지루한 개론 부분이었다면 앞으로는 실용적인 측면을 가미한 내용으로 찾아뵙도록 하겠습니다.

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