본문 바로가기

데이터베이스(DA, AA, TA)/Oracle

[오라클] RAC 튜닝 방법(1) - gc cr/current block 2-way/3-way

gc cr/current block 2-way/3-way


gc cr/current block 2-way 이벤트는 gc cr/current request 이벤트에 대한 Fixed-up 이벤트로, 블록을 요청한 프로세스가 마스터 노드로부터 직접 블록 이미지를 전송 받았다는 것을 의미합니다. gc cr/current request 이벤트가 gc cr/current block 2-way 이벤트로 바뀌는(Fixed-up되는) 흐름은 다음과 같습니다.


- 요청 노드의 유저 프로세스가 특정 데이터 블록을 CR 모드 또는 Current 모드로 읽고자 한다.

- 유저 프로세스는 해당 데이터 블록의 적절한 버전이 로컬 버퍼 캐시에 없는 것을 확인하고, 마스터 노드의 LMS(Lock Monitor Services) 프로세스에 블록 전송을 요청한다. 유저 프로세스는 응답을 받을 때까지 gc cr request 이벤트나 gc current request 이벤트를 대기한다.

- 마스터 노드의 LMS(Lock Monitor Services) 프로세스는 자신의 로컬 버퍼 캐시에 요청 받은 블록 이미지가 존재하는 것을 확인하고, 인터커넥트를 통해 해당 블록 이미지를 전송한다. CR 블록을 전송하는 경우에는 gc cr blocks served, gc cr block build time, gc cr block flush time, gc cr block send time 통계 값이 증가하고, Current 블록을 전송하는 경우에는 gc current blocks served, gc current block pin time, gc cr block flush time, gc cr block send time 통계 값이 증가한다.

- 유저 프로세스는 블록 이미지를 전송 받고, gc cr/current request 이벤트를 Fixed-up 이벤트인 gc block 2-way 이벤트나 gc current block 2-way 이벤트로 변경한다. CR 블록을 전송받은 경우에는 gc cr blocks received, gc cr block receive time 통계값이 증가하고, Current 블록을 전송받은 경우에는 gc current blocks received, gc current block receive time 통계 값이 증가한다.


* gc cr/current block 2-way 흐름

(유저 노드)gc cr/current request ▶ (마스터노드)gc cr blocks served, gc cr block build time, gc cr block flush time, gc cr block send time / gc current blocks served, gc current block pin time, gc cr block flush time, gc cr block send time 통계값 증가 ▶ (유저 노드)Fixed-up 이벤트 gc cr/current block 2-way 이벤트로 변경한다. gc cr blocks received, gc cr block receive time / gc current blocks received, gc current block receive time 통계값 증가


오라클은 이미 로컬 캐시에 읽을 수 있는 버전의 블록이 존재하면 즉 현재 SQL 문장이 요구하는 SCN(System Commit Number)을 만족하는 블록이 로컬 캐시에 존재한다면 추가적인 글로벌 캐시 동기화 작업을 수행하지 않고, 로컬 캐시에 있는 블록 이미지를 사용합니다. 따라서 SQL 문장 튜닝과 효율적인 버퍼 캐시 사용을 통해, 일단 로컬 캐시로 읽어 들인 블록들을 최대한 재활용하는 것이 RAC을 위한 최고의 튜닝 방법이 됩니다.


로컬 캐시에 읽을 수 있는 버전이 존재하는 경우, 글로벌 캐시 동기화를 수행하지 않는 정확한 조건을 이해할 필요가 있습니다.


RAC(Real Application Cluster) 시스템에서 "CR 모드로 읽을 수 있는 버전의 블록"의 정확한 의미는 "공유 모드(Shared Mode)로 BL(Buffer Hash Table Instance) 락을 획득한 블록"을 말합니다. 즉, 로컬 버퍼 캐시에 BL 락을 공유 모드로 획득한 블록이 존재하는 경우에는 글로벌 캐시 동기화 작업 없이 로컬 버퍼 캐시에서 바로 블록을 읽어들입니다. 요청 노드의 유저 프로세스가 CR 모드의 블록 전송을 요청한 후에 데이터 블록에 대해 공유모드로 BL(Buffer Hash Table Instance) 락을 획득하는 경우는 다음과 같습니다.


* 전체 클러스터에서 최초로 블록을 읽어 들이는 경우

이경우 gc grant 2/3-way 이벤트가 Fixed-up 이벤트로 사용된다.


* 홀더 노드가 공유 모드(Shared Mode)로 읽어 들인 블록을 전송받는 경우

이 경우 gc cr block 2-way/3-way 이벤트가 Fixed-up 이벤트로 사용된다. 하나의 블록에 대해 여러 노드가 동시에 공유 모드로 BL 락을 획득하게 된다.


* 홀더 노드가 독점 모드(Exclusive Mode)로 읽어 들인 블록을 전송 받되, 이 블록이 _FAIRNESS_THRESHOLD 파라미터 값(기본값은 4)을 초과하여 전송된 경우

이 경우에는 gc current block 2-way/3-way 이벤트가 Fixed-up 이벤트로 사용된다. 특정 블록을 독점 모드로 보유하고 있는 홀더 노드는, 해당 블록에 대해 CR 모드의 전송이 요청된 경우, 가능한 자신이 현재 보유한 독점 모드의 락을 유지한다.

락 다운그레이드가 지나치게 자주 발생하는 것을 방지하기 위해서이다. 이 경우 요청 노드는 공유 모드가 아닌 널 모드(Null Mode)로 BL 락을 확득한다.

하지만, 요청 노드가 계속해서 락 다운그레이드 요청을 하는 경우에는 즉, CR 모드 요청을 하는 경우에는, 독점 모드의 락을 공유 모드(Shared Mode)로 다운그레이드하고, 다른 노드가 BL 락을 공유 모드로 획득하는 것을 허용한다. 

이것을 제어하는 파라미터가 _FAIRNESS_THRESHOLD 파라미터로, 말 그대로 "노드 간에 공평성을 제어하는" 역할을 한다.


_FAIRNESS_THRESHOLD 임계치를 초과하여 락 다운그레이드가 발생한 경우의 수는 V$CR_BLOCK_SERVER 뷰를 통해 확인할 수 있습니다.


SQL> SELECT cr_requests, fairness_down_converts FROM V$CR_BLOCK_SREVER;

CR_REQUESTS            FAIRNESS_DOWN_CONVERTS

-----------------          -----------------------------------

38726154                  1973959


전체 CR 블록 요청 횟수 대비 락 다운그레이드 발생횟수가 약 5% 정도로 양호한 수치를 보인다.


CR 블록 요청에 의한 락 다운그레이드 발생 횟수가 지나치게 높은 경우에는(25% 이상), _FAIRNESS_THRESHOLD 파라미터 값을 1이나 2정도로 낮추는 것을 고려할 필요가 있습니다. 락 다운그레이드 횟수가 높다는 것은 거꾸로 CR 블록 요청에 대해 추가적인 블록 전송(최대 네 번까지)이 많이 발생한다는 것을 의미하기 때문입니다. 이런 경우에는 락 다운그레이드가 빨리 이루어지도록 하면, 그만큼 추가적인 블록전송이 없어지기 때문에 성능 선응 개선에 도움이 될 수 있습니다.



* _FAIRNESS_THRESHOLD 파라미터에 의해 글로벌 캐시 동기화 테스트

-- 두 개의 노드로 이루어진 RAC 환경이며, 오라클 버전은 10g R1이다.

-- SQL#1: 노드 1, SQL#2: 노드 2

SQL#2> CREATE TABLE rac_test(id NUMBER);

SQL#2> INSERT INTO rac_test VALUES(1); COMMIT;

-- File#-14, Block#=10307 블록

SQL#2>

SELECT DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) AS file#,

DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) AS block#

FROM rac_test;

FILE#       BLOCK#

---------   -----------

14           10307


-- 노드 2에서 다음 명령을 수행한다. 노드 2가 14번 데이터 파일의 마스터 노드가 된다.

SQL#2> connect /as sysdba

SQL#2> oradebug lkdebug -m pfile 14

(오라클 10g R2에서는 oradebug lkdebug -m pkey [object_no] 명령을 사용한다)


-- 노드 2에서 rac_test 테이블에 대해 업데이트(Update)를 수행해서 10307번 블록에 대해 독점 모드로 BL(Buffer Hash Table Instance) 락을 획득한다. 단, 이때 언두 정보를 참조할 필요가 없도록 반드시 Commit을 수행한다.

SQL#2> UPDATE rac_test SET id=2;

SQL#2> COMMIT;


-- 노드 1에서 총 6번의 SELECT, 즉 일관된 읽기 모드로 블록을 요청한다.

SQL#1> SELECT * FROM rac_test;

SQL#1> /

... (같은 쿼리를 6번 수행) ...

-- 노드1에서 수행한 6번의 쿼리를 SQL Trace를 통해 추적한 결과는 다음과 같다.

SQL#1> ho vi /admin/LAS10/udump/ora102_ora_19049.trc


-- 1번째 요청. gc cr block 2-way 이벤트를 대기하는 것을 확인할 수 있다.

SELECT * FROM rac_test

...

WAIT #6: nam='gc cr block 2-way' ela=1584 p1=14 p2=10307 p3=1


-- 2번째 요청. 역시 gc cr block 2-way 이벤트를 대기

WAIT #7: nam='gc cr block 2-way' ela=1203 p1=14 p2=10307 p3=1


-- 3번째 요청

WAIT #2: nam='gc cr block 2-way' ela=1640 p1=14 p2=10307 p3=1


-- 4번째 요청. _FAIRNESS_THRESHOLD 파라미터의 값(4)에 도달

WAIT #2: nam='gc cr block 2-way' ela=1206 p1=14 p2=10307 p3=1


-- 5번째 요청. 노드 2에서 락 다운그레이드가 발생했으며, 그 결과로 Current 블록을 전송 받았음을 확인할 수 있다. 대기 이벤트가 gc current block 2-way로 바뀐 것에 주목하자. 노드 2는 독점 모드의 BL 락을 공유 모드로 다운그레이드 하고, 노드 1은 공유 모드의 BL 락을 획득하게 된다.

WAIT #12: nam='gc current block 2-way' ela=1174 p1=14 p2=10307 p3=1


-- 6번째 요청

노드 1이 해당 블록에 대해 공유 모드로 BL 락을 획득했기 때문에, 글로벌 캐시 동기화 작업으로 인한 대기 현상이 발생하지 않는다. 


RAC 시스템에서 "Current 모드로 읽을 수 있는 버전의 블록"의 정확한 의미는 "독점 모드(Exclusive Mode)로 BL 락을 획득한 블록"을 말합니다. 즉, 로컬 버퍼 캐시에 BL 락을 독점 모드로 획득한 블록이 존재하는 경우에는 글로벌 캐시 동기화 작업없이 로컬 버퍼 캐시에서 바로 블록을 읽어 들입니다. 요청 노드의 유저 프로세스가 Current 모드의 블록 전송을 요청한 후에 데이터 블록에 대해 독점 모드로 BL 락을 획득하는 경우는 다음과 같습니다.


* 전체 클러스터에서 최초로 블록을 읽어 들이는 경우

이 경우 gc current grant 2-way/3-way 이벤트가 Fixed-up 이벤트로 사용된다.


* 홀더 노드가 공유 모드(Shared Mode)로 읽어 들인 Current 블록을 전송받는 경우

이 경우 gc current block 2-way/3-way 이벤트가 Fixed-up 이벤트로 사용된다.


* 홀더 노드가 독점 모드(Exclusive Mode)로 읽어들인 Current 블록을 전송 받은 경우

이 경우 gc current block 2-way/3-way 이벤트가 Fixed-up 이벤트로 사용된다. 이 과정에서 요청 노드는 트랜잭션 정보를 위해 언두 세그먼트 헤더 블록과 언두 블록을 추가로 전송 받게 되며, 해당 블록에 블록에 대해서는 gc cr block 2-way/3-way 이벤트 대기가 관찰된다. 만일 홀더 노드가 블록 변경 후 커밋을 수행하지 않는다면, 요청 노드는 계속해서 언두 정보를 참조해야 하므로 gc cr block 2-way/3-way 이벤트 대기가 증가할 수 있다. 요청 노드는 Current 블록을 전송하고 난 후, 해당 블록을 과거 이미지(PI. Past Image) 블록으로 전환한다.


독점 모드의 Current 블록을 Current 모드로 전송하는 경우(이것을 흔히 Write-Write 경쟁이라고 부른다)에는 항상 PI 블록이 생성됩니다. 따라서 클러스터 내에 하나의 블록에 대한 PI 블록이 여러개 존재할 수 있습니다. PI 블록은 로컬 인스턴스 레벨의 독점 모드의 Current 블록이라고 할 수 있습니다.


비록 클러스터 전체 레벨에서는 단 하나만의 독점 모드의 Current 블록이 존재하지만, 각 인스턴스 레벨에서 개별적인 Current 블록(PI 블록)을 가지고 있는 셈입니다. 이 경우 클러스터 전체 레벨의 Current 블록만이 디스크에 기록되는 메커니즘이 보장되어야 합니다. 


특정 인스턴스에서 더티 버퍼를 기록할 필요가 생기면, 자신이 직접 기록하지 않고 마스터 노드에게 클러스터 전체 레벨에서의 Current 블록을 기록할 것을 요청합니다. 마스터 노드는 GRD를 통해 홀더 노드에 디스크 기록을 요청하고, 디스크 기록이 성공하면 다른 모든 인스턴스에게 PI 블록을 버퍼 캐시에서 해제할 것을 알립니다. 이러한 일련의 과정을 Fusion Write라고 부릅니다. 오라클은 Fusion Write를 통해 오직 하나의 최신 블록 만이 디스크에 기록되는 것을 보장하고, 불필요한 PI 블록들을 메모리에서 해제하는 방법을 제공합니다. 


V$SYSSTAT 뷰를 통해 DBWR(Database Buffer Cache의 내용을 데이터 파일에 저장하는 작업을 수행) 프로세스에 의한 디스크 기록 작업 중 Fusion Write가  얼마나 많은 비중을 차지하는지 확인할 수 있습니다.


SQL> SELECT name, value FROM V$SYSSTAT WHERE name like '%DBWR%';

NAME                                          VALUE

----------------------------------------   -----------

DBWR checkpoint buffers written             28039411

...

DBWR fusion writes                         8524130



1) 일관된 읽기 모드 요청에 대해 현재 모드의 블록을 전송하는 경우

홀더 노드가 Current 블록을 로컬 캐시에 가지고 있는 상황에서, 다른 노드들이 _FAIRNESS_THRESHOLD 파라미터 값(4)을 초과하여 CR모드로 블록을 요청한 경우에는, CR모드가 아닌 Current 모드의 블록 이미지를 전송 받는다. 이 경우 요청 노드는 gc cr block 2-way/3-way 이벤트가 아닌 gc current block 2-way/3-way 이벤트를 Fixed-up 이벤트로 사용한다. 또한, 요청 노드에서는 gc current blocks received, gc current receive time 통계 값이 증가하고, 홀더 노드에서는 gc current blocks served, gc current block pin time, gc current block flush time, gc current block send time 통계 값이 증가한다.


2) 현재 모드의 블록 요청에 대해 일관된 읽기 모드의 블록을 전송하는 경우

Update 문과 같은 DML 수행에서는 Current 블록을 요청한다. 홀더 노드에서 이미 변경된 블록을 전송 받는 경우에는 추가적으로 언두 세그먼트 헤더 블록과 언두 블록의 정보를 인관된 읽기 모드로 전송 받아야 한다. 이들 블록에 트랜잭션 정보가 관리되기 때문이다.


DML 수행 후, 지나치게 장시간 커밋을 수행하지 않으면 언두 세그먼트 헤더 블록이나 언두 블록의 CR 버전이 전송되어야 하므로, 불필요한 인터커넥트 경합을 유발할 수 있다는 사실을 기억해야 합니다. 특정 노드의 장시간의 트랜잭션을 수행하는 도중에, 다른 노드에서 DML을 수행하게 되면 언두 정보 참조를 위해 추가적인 블록 전송이 이루어지고, gc cr block 2-way/3-way 이벤트 대기로 관찰됩니다.


간단한 테스트를 통해 DML 수행시에 CR 블록 전송이 이루어지는 것을 확인할 수 있습니다.


마스터노드가 노드 2인 rac_test 테이블. id=2, id=3에 해당하는 로우가 같은 블록에 있는 로우임을 확인

SQL#2> SELECT id, dbms_rowid.rowid_block_number(rowid) FROM rac_test;

ID DBMS_       ROW.ROWID_BLOCK_NUMBER(ROWID)

--------------- ----------------------------------------------------------------------------------

2                   10299

3                   10299


노드2에서 id=2에 대해 Update 수행 후, Commit을 수행하지 않음

SQL#2> UPDATE rac_test SET id = id WHERE id = 2;


노드1에서 로우 레벨 락이 걸리지 않도록 id=3에 대해 Update 수행

SQL#1> UPDATE rac_test SET id=id WHERE id=3;

SQL#1> /


노드1에서 Update 문을 여러 차례 수행한 후, 수행 결과를 SQL Trace를 통해 추적하면 아래와 같다.


update rac_test set id = id where id = 3

WAIT #1: nam='gc cr block 2-way' ela=1375 p1=8 p2=104457 p3=93

WAIT #1: nam='SQL*Net message to client' ela=23 p1=16508 p2=1 p3=0

WAIT #1: nam='SQL*Net message from client' ela=356 p1=16508 p2=1 p3=0

...

P1(file#)=8, P2(block#)=104457, P3(2*r+15,r=39)=93인 언두 세그먼트 헤더 블록 정보를 얻는 과정에서 gc cr block 2-way 이벤트를 대기하는 것을 알 수 있다.

또한 DBA_ROLLBACK_SEGS 뷰를 조회해보면, 39번 언두 세그먼트의 헤더 블록임을 확인할 수 있다.

SQL#2> EXEC print_table('SELECT * FROM DBA_ROLLBACK_SEGS WHERE file_id=8 AND block_id=104457');

--------------------------------------------------------------

SEGMENT_NAME                    : RAC02_06

OWNER                           : PUBLIC

TABLESPACE                      : TEST_DATA

SEGMENT_ID                      : 39

FILE_ID                         : 8

BLOCK_ID                        : 104457

INITIAL_EXTENT                  : 2097152

NEXT_EXTENT                     :

MIN_EXTENT                      : 1

MAX_EXTENT                      : 32765

PCT_INCREASE                    :

STATUS                          : ONLINE

INSTANCE_NUM                    : 1

RELATIVE_FNO                    : 8


* Parameter

gc cr block 2-way이벤트와 같은 Fixed-up 이벤트는 P1, P2, P3 값이 별도로 부여되지 않으며, Placeholder 이벤트(여기서는 gc cr request 이벤트)와 동일한 값을 가지는 것으로 해석하면 된다.



2-way와 3-way의 차이


두 개의 노드로 이루어진 RAC 환경에서는 최대 2회(2-way)의 통신이 이루어집니다. 하지만, 세 개 이상의 노드로 이루어진 RAC 환경에서는 최대 3회(3-way)까지 통신이 이루어집니다. 3회의 통신을 통해 블록 이미지를 전송받은 경우에는 gc cr/current block 3-way 이벤트를 Fixed-up 이벤트로 사용합니다. 3-way 통신은 클러스터 환경에서는 필연적으로 발생하며, 이 현상 자체를 튜닝하려는 노력은 무의미합니다. 하지만, 3-way 통신이 지나치게 많다는 것은 마스터 노드가 잘못 할당되어 있다는 것을 암시할 수도 있습니다. 오라클 10g R2부터는 세그먼트 레벨의 다이나믹 리마스터링이 지원되므로, 잘못된 마스터 노드지정에 의한 불필요한 인터커넥트 통신이 자연스럽게 줄어듭니다.



* gc cr blocks served

다른 인스턴스의 CR 블록 요청으로 인해 전송(Send/Serve)된 블록의 개수를 의미합니다. 이름과 달리 이 통계 값이 전송된 "CR 블록의 수"만을 의미하는 것이 아니라는 사실에 주의할 필요가 있습니다. CR 블록 요청에 대해 Current  블록을 전송하는 경우도 있기 때문입니다.


gc cr blocks served 통계 값은 항상 gc cr block build time, gc cr block flush time, gc cr block send time 통계 값과 함께 분석해야 합니다. CR 블록을 전송하는 과정은 CR 블록 구성(Build), CR 블록 리두 플러시(Flush)와 CR 블록 전송(Send)를 포함하기 때문입니다.



* gc cr block build time

다른 인스턴스의 CR 블록 요청으로 인해 CR 블록을 전송하는 과정은 CR 블록을 구성(Build)하는데 소요된 시간을 의미합니다. 단위는 1/100초(cs)입니다. CR 블록의 구성(Build)은 버퍼 캐시로부터 CR 블록을 탐색하는 시간과 버퍼 캐시에 CR 블록이 존재하지 않는 경우에 디스크로부터 CR 카피(Copy)를 생성하는 시간을 포함합니다.

이 작업이 LMS(Lock Monitoring Services) 프로세스에 큰 부하를 유발할 수 있기 때문에 오라클은 요청된 SCN과 가장 큰접한 블록으로부터 CR 블록을 생성(이 과정을 CR 카피라고 함)합니다. 즉, 디스크로부터 언두 이미지를 반영하지 않고 불완전한 이미지의 CR 블록을 생성한 후 전송합니다. 불완전한 CR 블록을 전송받은 요청 노드의 프로세스가 직접 언두를 수행해서 완전한 이미지의 CR 블록을 생성합니다. 

이것을 흔히 Light Weight Rule이라고 부릅니다. CR 블록을 구성(Build)하는 작업은 메모리 탐색과 메모리 복사 작업을 포함하기 때문에 CPU 자원을 많이 필요로 하며, 이 일련의 작업들을 LMS 프로세스가 담당합니다. 만일 CR 블록 구성에 많은 시간이 소모된다면 LMS 프로세스의 성능에 대한 점검이 필요합니다.



* gc cr block flush time

다른 인스턴스의 CR 블록 요청으로 인해 Current 블록을 전송하는 과정에서 리두 플러시(Redo Flush)에 소요된 시간을 의미합니다. 단위는 1/100초(cs)입니다. 오라클은 요청된 CR 블록에 대해 Current 이미지로 만족 가능한 경우에는 CR 카피 작업을 수행하지 않고 Current 블록을 직접 전송합니다.

만일 Current 블록이 현재 더티(Dirty) 상태라면 리두 로그에 변경 내역을 기록한 후 전송해야 합니다. 만일 리두 플러시에 많은 시간이 소모된다면 LGWR 프로세스의 성능이나 리두 로그 파일의 I/O 성능에 대한 점검이 필요합니다. gcs log flush sync 대기 이벤트와 gc cr block busy 대기 이벤트와 연관해서 분석하면 더욱 정확한 진단을 내릴 수 있습니다.



* gc current blocks served

다른 인스턴스의 Current 블록 요청으로 인해 전송(Send, Serve)된 블록의 개수를 의미합니다. 

gc current blocks served 통계 값은 항상 gc current block pin time, gc current block flush time, gc current block send time 통계 값과 함께 분석해야 합니다. Current 블록을 전송하는 과정은 Current 블록에 대한 락 획득(Pin), Current 블록 리두 플러시(Flush)와 Current 블록 전송(Send)을 포함하기 때문입니다.



* gc cr block send time

다른 인스턴스의 CR 블록 요청으로 인해 블록을 전송하는 과정에서 네트워크 전송(Send)에 소요된 시간을 의미합니다. 단위는 1/100초(cs)입니다. 이 값의 의미를 정확하게 이해하려면 블록 전송 과정이 버퍼 캐시 레이어와 네트워크 레이어라는 두 개의 레이어에 의해 이루어진다는 사실을 이해해야 합니다. 버퍼 캐시 레이어로부터 시작된 블록 전송 요청은 다음과 같은 과정을 통해 물리적인 전송이 이루어집니다.


버퍼 캐시 레이어에서 전송할 블록을 준비한 다음(gc cr block build time, gc cr block flush time), 네트워크 레이어로 블록을 전달합니다.


네트워크 레이어에서는 OS가 관리하는 네트워크 서브 시스템에 블록 전송 요청을 전달합니다.


네트워크 서브 시스템은 전송 큐(가령 UDP Send Buffer)에 전송 데이터를 추가한 후, 네트워크 레이어에 전송에 성공했음을 알립니다. 전송 큐에 데이터를 추가하는 것이 곧 물리적으로 데이터가 전송된다는 것을 의미하지는 않는다는 사실에 주의해야 합니다.


네트워크 레이어는 버퍼 캐시 레이어에 블록 전송이 성공했음을 알립니다.


즉, gc cr block send time 통계 값은 실제 블록 전송에 걸린 시간이 아닌, 네트워크 레이어에 블록전송 요청을 한 후 응답을 받을 때까지 걸린 시간을 의미합니다. 일반적으로 OS 레벨에서의 네트워크 전송 요청은 매우 빠른 속도로 이루어지기때문에 gc cr block send time 통계 값이 차지하는 비중은 높지 않습니다.


만일 gc block send time 통계 값이 다른 통계 값과 비교해 높은 비중을 차지한다면 네트워크 설정이나 네트워크 드리이브, 하드웨어 설정 등에 문제가 있는지 점검해 볼 필요가 있습니다.



* gc current block pin time

다른 인스턴스의 Current 블록 전송 요청을 처리하기 위해 Current 블록에 대한 락을 획득하는데 소요된 시간을 의미합니다. 단위는 1/100초(cs)입니다. 락을 획득하는 작업을 보통 핀(Pin)이라고 부르는 데서 비롯한 이름입니다. 락 획득 과정에서 시간이 소요되는 사유에는 크게 두 가지가 존재합니다.


1) _GC_DEFER_TIME 파라미터로 의한 블록 전송 지연의 경우

만일 전송 대상인 Current 블록에 대해 블록 클린 아웃 작업이 아직 이루어지지 않았다면 오라클은 _GC_DEFER_TIME 파라미터 값(기본값은 3ms)만큼 대기한 후 락을 획득한다


2) 블록 경합이 발생하는 경우

전송 대상인 Current 블록을 다른 로컬 프로세스가 사용 중이라면 락을 획득할 수 없습니다. 만일 블록 경합이 매우 심해서 즉, 수많은 로컬 프로세스가 같은 블록에 대해 경쟁을 하는 상황이라면 버퍼 전송을 위해 글로벌 락을 획득하는 과정에서 많은 시간을 소모하게 됩니다.


gc current block pin time 통계값이 차지하는 비중이 지나치게 높은 경우에는 핫 블록의 존재 여부를 확인해보아야 하며, 블록 경합이 지나치게 자주 발생하지 않는지 점검해 보아야 합니다. buffer busy waits 대기 이벤트와 gc current block busy 대기 이벤트와 연계해서 분석하면 더욱 정확한 진단을 내릴 수 있습니다. 또한 V$CURRENT_BLOCK_SERVER 뷰를 활용하면 Current 블록에 대한 락 획득의 성능 문제를 좀 더 세밀하게 분석할 수 있습니다.



* gc current clock send time

다른 인스턴스의 Current 블록 요청으로 인해 블록을 전송하는 과정에서 네트워크 전송(Send)에 소요된 시간을 의미합니다.



* gc current block flush time

다른 인스턴스의 Current 블록 요청으로 인해 Current 블록을 전송하는 과정에서 리두 플러시(Redo Flush)에 소요된 시간을 의미합니다. 단위는 1/100초(cs)입니다. 전송 대상인 Current 블록이 현재 더티(Dirty) 상태라면 리두 로그에 변경 내역을 기록한 후 전송해야합니다. 만일 리두 플러시에 많은 시간이 소모된다면 LGWR 프로세스의 성능이나 리두 로그 파일의 I/O 성능에 대한 점검이 필요합니다.


gcs log flush sync 대기 이벤트와 gc current block busy 대기 이벤트와 연관해서 분석하면 더욱 정확한 진단을 내릴 수 있습니다. 또한 V$CURRENT_BLOCK_SERVER 뷰를 참조하면 Current 블록에 대한 리두 플러시의 성능 문제를 좀 더 세밀하게 분석할 수 있습니다.



* gc cr block received

다른 인스턴스에 CR 블록 전송을 요청한 후 전송 받은 블록 수를 의미합니다. gc cr blocks received 통계 값은 gc cr blocks served 통계 값과 일대일 관계를 지닙니다. 만일 두개의 인스턴스로 이루어진 RAC 시스템이라면 다음과 같은 관계를 지닙니다.


[1번 인스턴스의 gc blocks recevied ≒ 2번 인스턴스의 gc cr blocks served]


gc cr blocks served 통계 값에서 설명한 바와 같이 CR 블록 전송 과정에서 Light Weight Rule이 적용된 경우에는 불완전한 버전의 CR 블록을 전송받습니다. 이 경우에는 요청 인스턴스에서 CR 블록 구성 작업을 마무리하게 됩니다. 특히 리모트 인스턴스에서 빈번한 블록 변경 작업이 발생했다면 Light Weight Rule이 자주 적용되게 됩니다. 불완전한 CR 블록을 전송받은 요청 인스턴스는 CR 블록을 완성하기 위해 디스크에서 언두 이미지를 읽거나 언두 세그먼트 헤더 블록 정보를 다시 리모트 인스턴스로부터 전송 받는 일련의 추가적인 작업을 수행해야 합니다. Light Weight Rule은 홀더 인스턴스의 LMS 프로세스의 부하를 줄이는 대신, 그 부담을 요청 인스턴스의 서버 프로세스가 나누어 가지는 것으로 이해할 수 있습니다.



* gc cr block receive time

다른 인스턴스에 CR 블록 전송을 요청한 후 전송 받을 때까지 소요된 시간을 의미합니다. 단위는 1/100초(cs)입니다. gc cr block receive time 통계 값은 gc cr block build time, gc cr block flush time, gc cr block send time 통계 값에 실제 네트워크 송수신에 소모된 시간을 합친 값으로 이해하면 됩니다. 만일 두 개의 인스턴스로 이루어진 RAC 시스템이라면 다음과 같은 관계를 지닙니다.


[1번 인스턴스의 gc cr block receive time =

2번 인스턴스의 gc cr block build time + gc cr block flush time + gc cr block send time + 전송 요청을 전달하는데 걸린 시간 + 요청에 대한 응답을 전달하는데 걸린 시간]


만일 네트워크 전송 성능이 느리다면 요청 인스턴스가 실제 블록을 받을 때까지 걸린 시간이 홀더 인스턴스가 전송하는데 걸리는 시간에 비해 매우 높게 나올 수 있습니다. 따라서 이런 경우에는 네트워크 성능을 점검해 보아야합니다.



* gc current blocks received

다른 인스턴스에 Current 블록 전송을 요청한 후 전송 받은 블록 수를 의미합니다. gc current blocks received 통계값은 gc current blocks served 통계 값과 일대일 관계를 지닙니다. 만일 두개의 인스턴스로 이루어진 RAC 시스템이라면 다음과 같은 관계를  지닙니다.


[1번 인스턴스의 gc current blocks received ≒ 2번 인스턴스의 gc current blocks served]



* gc current block receive time

다른 인스턴스에 Current 블록 전송을 요청한 후 전송 받을때까지 소요된 시간을 의미합니다. gc current block receive time 통계 값은 gc current block build time, gc current block flush time, gc current block send time 통계 값에 실제 네트워크 송수신에 소모된 시간을 합친 값으로 이해하면 됩니다. 만일 두 개의 인스턴스로 이루어진 RAC 시스템이라면 다음과 같은 관계를 지닙니다.


[1번 인스턴스의 gc current block receive time =

2번 인스턴스의 gc current block pin time + gc current block flush time + gc current block send time + 전송 요청을 전달하는데 걸린 시간 + 요청에 대한 응답을 전달하는데 걸리는 시간]


만일 네트워크 전송 성능이 느리다면 요청 인스턴스가 실제 블록을 받을 때까지 걸린 시간이 홀더 인스턴스가 전송하는데 걸린 시간에 비해 매우 높게 나올 수 있습니다. 따라서 이런 경우에는 네트워크 성능을 점검해 보아야 합니다.



* gc blocks lost

블록 전송 과정에서 유실(Lost)된 블록의 수를 의미합니다. 블록 유실은 RAC 시스템의 성능에[ 결정적인 영향을 미치기 때문에 gc blocks lost 통계 값은 가능한 낮은 수치를 유지해야 합니다. 만일 gc blocks lost 통계값이 증가한다면 다음과 같은 확인 절차를 거쳐야 합니다.


네트워크 설정이나 하드웨어 설정에 이상이 없는가를 점검합니다. netstat와 같은 툴을 이용해서 네트워크 패킷 에러가 발생하지 않는지 점검하고, 네트워크 파라미터가 지나치게 작게 설정되어 있지 않는지 확인합니다. 네트워크 버퍼 크기를 크게하고, MTU(Maximum Transmission Unit)의 크기를 크게하는 것 등도 해결 방법이 될 수있습니다.


잘못된 네트워크 프로토콜을 사용하고 있지 않는가를 점검합니다. 재부분의 OS에서 오라클은 UDP를 기본 프로토콜로 사용할 것을 권장합니다. 많은 종류의 프로토콜에 대해 RAC 성능 테스트와 적용이 이루어졌지만, UDP에서 가장 안정적으로 작동하는 것이 경험적으로 검증되었습니다. 만일 특정 벤더가 제공하는 특정 프로토콜을 사용한다면 반드시 오라클로부터 검증을 거쳐야 합니다.


지나치게 인터커넥트 부하가 높은 경우에는 패킷 유실을 피할 수 없습니다. 이 경우에는 네트워크 대역폭을 높이거나 SQL/애플리케이션 튜닝을 통해 블록 전송 수를 줄여야 합니다.



* blocks corrupt

블록 전송 과정에서 손상(Corrupt)이 발생한 블록 수를 의미합니다. 블록 손상 여부는 체크섬(Checksum) 값을 통해 확인됩니다. 블록 손상은 RAC 시스템의 성능에 결정적인 영향을 미치기 때문에 blocks corrupt 통계 값은 가능한 낮은 수치를 유지해야합니다. 블록 손상은 RAC 자체의 문제라기보다는 대부분 하부 레이어, 즉 네트워크 설정이나 하드웨어 설정에 의해 발생하는 문제로 봐야합니다. 만일 gc blocks corrupt 통계 값이 증가한다면, 비현실적인 네트워크 파라미터나 하드웨어 설정은 없는지 점검해야 합니다.



* gc CPU used by this session

글로벌 캐시 동기화 작업에 사용한 CPU 시간을 의미합니다. 단위는 1/100초입니다. 이 값을 전체 CPU 사용 시간과 비교하면 글로벌 캐시 동기화 작업에 얼마나 많은 CPU 자원을 사용하는지 추측할 수 있습니다. 오라클 통계 값으로 제공하는 CPU 사용 시간은 총 네 가지로 다음과 같습니다.


 - CPU used by this session: 전체 CPU 사용 시간

 - PC CPU used by this session: IPC 작업을 수행하는데 사용한 CPU 시간

 - global enqueue CPU used by this session: 글로벌 락 동기화 작업을 수행하는데 사용한 CPU 시간

 - gc CPU used by this session: 글로벌 캐시 동기화 작업을 수행하는데 사용한 CPU 시간


위의 값들을 비교해서 특정 작업의 CPU 자원이 전체 CPU 사용 시간 대비 얼마나 사용되는지 확인할 수있습니다. 오라클 10g부터 제공되는 타임 모델(Time Model)을 사용하면 더욱 풍부한 CPU 사용 시간 정보를 얻을 수 있습니다. V$SYS_TIME_MODEL 뷰를 통해 DB 작업의 소요시간을 추출할 수 있으며, 값의 단위는 1/1,000,0000 (micros)로, 각 DB 작업의 전체 소요 시간(DB Time)이나, CPU 사용 시간(DB CPU)에 비해 얼마나 높은 비중을 차지하는지 분석할 수 있습니다. DB Time 통계 값과 CPU used by this session 통계 값은 정확하게 일치하지는 않지만 비교적 비슷한 값을 제공합니다.