RAC 캐시 퓨전

  • 데이터베이스의 부하를 분산할 목적으로 시스템마다 다양한 분산전략을 사용하는데, 최근에는 데이터베이스를 물리적으로 분할하여 분산하는 방식이 아니라, 데이터베이스를 하나로 두되 이를 엑세스하는 인스턴스를 여러 개 두는 공유 디스크(Shared Disk)방식의 데이터베이스 클러스터링 기법이 도입되기 시작했다.
  • 오라클 RAC모델은 공유디스크 방식에 기반을 두면서 인스턴스 간에 버퍼캐시까지 공유하는 캐시퓨전(Cache Fusion)기술로 발전하였다.
  • 많은 장점이 있는데도 불구하고, 튜닝이 잘 되지 않아 많은 블록I/O를 일으키는 애플리케이션에서 RAC를 도입하면, 단일 인스턴스 환경에서보다 더욱 심각한 성능저하현상이 나타나며, RAC 모델특성 상 발생하는 성능문제를 해결하기 위해서는 캐시퓨전 프로세싱 원리를 이해할 필요가 있다.
  • 글로벌 캐시
    • 클러스터링 되어있는 모든 인스턴스 노드의 버퍼캐시를 하나의 버퍼캐시로 간주한다.
    • 모든 데이터 블록에 대해서 마스터 노드가 각각 정해져 있고, 그 노드를 통해서 글로벌 캐시에 캐싱되어 있는 블록의 상태와 Lock정보를 관리한다.
  • Current 블록
    • Shared 모드 Current(SCur)와 Exclusive 모드 Current(XCur)로 나뉨
    • SCur상태의 블록은 동시에 여러 노드에 캐싱될 수 있지만, XCur상태의 블록은 단 하나의 노드에만 존재할 수 있다.

RAC 노드간 버퍼캐시를 공유하면서 블록을 서로 주고받는 전송 매커니즘은 5가지로 나누어 설명할 수 있다

전송 매커니즘

  • 전송 없는 읽기: Read with No Transfer

  1. A노드는 그 블록의 리소스 마스터인 B 노드에게 전송 요청을 보낸다. 이때 gc cr request 이벤트에서 대기한다.
  2. B노드는 현재 어떤 노드에도 K블록을 캐싱하고 있지 않음을 확인하고 A노드에게 데이터파일에서 직접 블록을 SCur 모드로 읽도록 권한을 부여한다.
  3. A노드는 디스크에서 블록을 읽어 로컬 캐시에 캐싱한다.


2Node Case
local : 1 , global 0
mode_held : 0 (N), 1(S),2(X)
Node 1 
SQL> select b.lock_element_addr, b.status, e.mode_held, e.local 
  2  from v$bh b, v$gc_element e
  3  where b.file#=5 and b.block#=654
  4  and b.lock_element_addr = e.gc_element_addr;

no rows selected

SQL> /

LOCK_ELEMENT_ADD STATUS                 MODE_HELD      LOCAL
---------------- --------------------- ---------- ----------
0000000062BFBB10 scur                           1          1

Node 2

SQL> select b.lock_element_addr, b.status, e.mode_held, e.local 
  2  from v$bh b, v$gc_element e
  3  where b.file#=5 and b.block#=654
  4  and b.lock_element_addr = e.gc_element_addr;

no rows selected

SQL> 


  • 읽기/읽기 전송: Read to Read Transfer
  1. C노드는 리소스 마스터인 B노드에게 K블록에 대한 전송 요청을 보낸다.
  2. B노드는 현재 K블록을 A노드가 캐싱하고 있음을 확인하고 C노드에 블록을 전송해 주도록 A노드에게 지시한다.
  3. A노드는 C노드에게 블록을 전송해 준다.
  4. C노드는 블록을 성공적으로 전송받아 SCur 모드로 캐싱하게 되었음을 알리려고 마스터 노드인 B에게 메시지를 보낸다.


Node 1

LOCK_ELEMENT_ADD STATUS                 MODE_HELD      LOCAL
---------------- --------------------- ---------- ----------
0000000062BFBB10 scur                           1          1

Node 2

LOCK_ELEMENT_ADD STATUS                 MODE_HELD      LOCAL
---------------- --------------------- ---------- ----------
0000000062BFBB10 scur                           1          1



  • 읽기/쓰기 전송: Read to Write Transfer
  1. C노드는 마스터 노드인 B에게 K블록을 XCur 모드로 업그레이드하겠다고 요청한다.
  2. B노드는 현재 K블록을 A노드도 캐싱하고 있음을 확인하고 Null 모드로 다운그레이드하도록 지시한다.
  3. A노드는 C노드에게 Null 모드로 다운그레이드 했음을 알려준다.
  4. C노드는 K블록을 XCur모드로 업그레이드하고 그 결과를 마스터 노드인 B에게 알려준다. 이때 A노드의 K블록이 Null 모드로 다운그레이드 된것까지 함께 알려준다.
  • C노드의 K블록 SCN이 123 -> 154로 증가한다.

Node 1

SQL> select b.lock_element_addr, b.status, b.dirty, e.mode_held, e.local 
  2  from v$bh b, v$gc_element e
  3  where b.file#=5 and b.block#=654
  4  and b.lock_element_addr = e.gc_element_addr;

LOCK_ELEMENT_ADD STATUS                DIR  MODE_HELD      LOCAL
---------------- --------------------- --- ---------- ----------
0000000062BFBB10 xcur                  Y            2          0
0000000062BFBB10 pi                    Y            2          0

Node 2

SQL> select b.lock_element_addr, b.status, b.dirty, e.mode_held, e.local 
  2  from v$bh b, v$gc_element e
  3  where b.file#=5 and b.block#=654
  4  and b.lock_element_addr = e.gc_element_addr;

no rows selected


  • 쓰기/쓰기 전송: Write to Write Transfer
  1. A노드는 마스터 노드인 B에게 K블록을 XCur 모드로 요청한다.
  2. B노드는 현재 K블록을 C노드가 XCur 모드로 캐싱하고 있음을 확인하고 A노드에게 보내주도록 지시한다.
  3. C노드는 A노드에게 블록을 전송하고 자신이 갖고 있던 블록은 Null 모드로 다운그레이드한다.
  4. A노드는 K블록을 XCur 모드로 캐싱하게 됐음을 B노드에게 알려준다.
  • A노드의 K블록 SCN이 154 -> 168로 증가한다.

다른 인스턴스가 갱신 중인 블록을 읽고자 할 때 로우 Lock이 해제될 때까지 기다리지 않고 로우Lock이 설정된 채, 블록을 주고 받는다.



SQL> create table jin(id number);

Table created.

SQL> insert into jin values(1);
1 row created.

SQL> commit;

Commit complete.

SQL> select dbms_rowid.rowid_relative_fno(rowid) as fno, 
  2         dbms_rowid.rowid_block_number(rowid) as blkno
  3  from jin;

       FNO      BLKNO
---------- ----------
         5        212




*** 2012-07-25 19:30:20.370
*** SESSION ID:(55.59) 2012-07-25 19:30:20.370
*** CLIENT ID:() 2012-07-25 19:30:20.370
*** SERVICE NAME:(SYS$USERS) 2012-07-25 19:30:20.370
*** MODULE NAME:(SQL*Plus) 2012-07-25 19:30:20.370
*** ACTION NAME:() 2012-07-25 19:30:20.370
 
Start dump data blocks tsn: 5 file#:5 minblk 212 maxblk 212
Block dump from cache:
Dump of buffer cache at level 4 for tsn=5, rdba=20971732
BH (0x707b33d0) file#: 5 rdba: 0x014000d4 (5/212) class: 1 ba: 0x70474000
  set: 3 pool: 3 bsz: 8192 bsi: 0 sflg: 1 pwc: 0,0
  dbwrid: 0 obj: 57623 objn: 57623 tsn: 5 afn: 5 hint: f
  hash: [0x707b3308,0x758fe610] lru: [0x6efaf880,0x707b3340]
  lru-flags: moved_to_tail on_auxiliary_list
  ckptq: [NULL] fileq: [NULL] objq: [NULL] objaq: [NULL]
  st: FREE md: NULL tch: 0 lfb: 33 le: (nil)
  flags:
  cr pin refcnt: 0 sh pin refcnt: 0
BH (0x707b3258) file#: 5 rdba: 0x014000d4 (5/212) class: 1 ba: 0x70472000
  set: 3 pool: 3 bsz: 8192 bsi: 0 sflg: 1 pwc: 0,0
  dbwrid: 0 obj: 57623 objn: 57623 tsn: 5 afn: 5 hint: f
  hash: [0x707d0a80,0x707b3480] lru: [0x707b34b8,0x707d0ab8]
  lru-flags: moved_to_tail on_auxiliary_list
  ckptq: [NULL] fileq: [NULL] objq: [NULL] objaq: [NULL]
  st: FREE md: NULL tch: 0 lfb: 33 le: (nil)
  flags:
  cr pin refcnt: 0 sh pin refcnt: 0
BH (0x707d09d0) file#: 5 rdba: 0x014000d4 (5/212) class: 1 ba: 0x706f4000
  set: 3 pool: 3 bsz: 8192 bsi: 0 sflg: 1 pwc: 0,0
  dbwrid: 0 obj: 57623 objn: 57623 tsn: 5 afn: 5 hint: f
  hash: [0x6d7b83d0,0x707b3308] lru: [0x707b3340,0x6d7b8408]
  lru-flags: moved_to_tail on_auxiliary_list
  ckptq: [NULL] fileq: [NULL] objq: [NULL] objaq: [NULL]
  st: FREE md: NULL tch: 0 lfb: 33 le: (nil)
  flags:
  cr pin refcnt: 0 sh pin refcnt: 0
BH (0x6d7b8320) file#: 5 rdba: 0x014000d4 (5/212) class: 1 ba: 0x6d4e0000
  set: 3 pool: 3 bsz: 8192 bsi: 0 sflg: 1 pwc: 0,0
  dbwrid: 0 obj: 57623 objn: 57623 tsn: 5 afn: 5 hint: f
  hash: [0x758fe610,0x707d0a80] lru: [0x707d0ab8,0x6f7d2f70]
  lru-flags: moved_to_tail on_auxiliary_list
  ckptq: [NULL] fileq: [NULL] objq: [NULL] objaq: [NULL]
  st: FREE md: NULL tch: 0 lfb: 33 le: (nil)
  flags: weak_clone
  cr pin refcnt: 0 sh pin refcnt: 0
Block dump from disk:
buffer tsn: 5 rdba: 0x014000d4 (5/212)
scn: 0x0281.d0ac886a seq: 0x01 flg: 0x06 tail: 0x886a0601
frmt: 0x02 chkval: 0x91b0 type: 0x06=trans data
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x00002B7A8BC1B200 to 0x00002B7A8BC1D200
2B7A8BC1B200 0000A206 014000D4 D0AC886A 06010281  [......@.j.......]
2B7A8BC1B210 000091B0 00000001 0000E117 D0AC87AE  [................]
2B7A8BC1B220 00000281 00320002 014000D0 00150016  [......2...@.....]
2B7A8BC1B230 00000003 01800094 00090000 02818000  [................]
2B7A8BC1B240 D0AC8597 001C001B 00000003 018000E9  [................]
2B7A8BC1B250 00310001 00002001 D0AC886A 00000000  [..1.. ..j.......]
2B7A8BC1B260 00000000 00010100 0014FFFF 1F7B1F92  [..............{.]
2B7A8BC1B270 00001F7B 1F920001 00000000 00000000  [{...............]
2B7A8BC1B280 00000000 00000000 00000000 00000000  [................]
        Repeat 502 times
2B7A8BC1D1F0 00000000 022C0000 04C10201 886A0601  [......,.......j.]
Block header dump:  0x014000d4
 Object id on Block? Y
 seg/obj: 0xe117  csc: 0x281.d0ac87ae  itc: 2  flg: E  typ: 1 - DATA
     brn: 0  bdba: 0x14000d0 ver: 0x01 opc: 0
     inc: 0  exflg: 0
 
 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0016.015.00000003  0x01800094.0000.09  C---    0  scn 0x0281.d0ac8597
0x02   0x001b.01c.00000003  0x018000e9.0001.31  --U-    1  fsc 0x0000.d0ac886a
bdba: 0x014000d4
data_block_dump,data header at 0x2b7a8bc1b264
===============
tsiz: 0x1f98
hsiz: 0x14
pbl: 0x2b7a8bc1b264
     76543210
flag=--------
ntab=1
nrow=1
frre=-1
fsbo=0x14
fseo=0x1f92
avsp=0x1f7b
tosp=0x1f7b
0xe:pti[0]      nrow=1  offs=0
0x12:pri[0]     offs=0x1f92
block_row_dump:
tab 0, row 0, @0x1f92
tl: 6 fb: --H-FL-- lb: 0x2  cc: 1
col  0: [ 2]  c1 04
end_of_block_dump
GLOBAL CACHE ELEMENT DUMP (address: 0x6fbfc4e0):
  id1: 0xd4 id2: 0x5 pkey: OBJ#57623 block: (5/212)
  lock: C rls: 0x0 acq: 0x0 latch: 0
  flags: 0x21 fair: 0 recovery: 0 fpin: 'kdswh11: kdst_fetch'
  bscn: 0x281.d0ac496a bctx: (nil) write: 0 scan: 0x0 
  lcp: (nil) lnk: [NULL] lch: [0x6f3f45a0,0x6bff89a0]
  seq: 42 hist: 329 144:6 14 7 144:5 192 352 329 144:6 14 7
 GCS SHADOW 0x6fbfc558,6 resp[(nil),0xd4.5] pkey 57623.0
   grant 0 cvt 0 mdrole 0x0 st 0x0 lst 0x40 GRANTQ rl LOCAL
   master 1 owner 1 sid 0 remote[(nil),0] hist 0x1163408b1a0458d
   history 0xd.0xb.0x1.0xd.0xb.0x1.0xd.0xb.0x1.0x0.
   cflag 0x0 sender 0 flags 0x0 replay# 0 abast (nil).x0.1 dbmap (nil)
   disk: 0x0000.00000000 write request: 0x0000.00000000
   pi scn: 0x0000.00000000 sq[0x6fbfc558,0x6fbfc558]
   msgseq 0x0 updseq 0x0 reqids[8,0,0] infop (nil) lockseq xfd
   pkey 57623.0
   hv 5 [stat 0x0, 1->1, wm 32768, RMno 0, reminc 0, dom 0]
   kjga st 0x4, step 0.0.0, cinc 6, rmno 3, flags 0x0
   lb 0, hb 0, myb 26, drmb 26, apifrz 0
 GCS SHADOW END
2012-07-25 19:30:20.449811 : kjbmbassert [0xd4.5]
2012-07-25 19:30:20.449875 : kjbmsassert(0xd4.5)(2)
2012-07-25 19:30:20.449898 : kjbmsassert(0xd4.5)(3)
End dump data blocks tsn: 5 file#: 5 minblk 212 maxblk 212
rraw1:/u00/diag/rdbms/rraw/rraw1/trace] 



#################################################

Dump block : Master 1 NODE, Grant 2 ;

19:19:13 jin@rraw1>select b.lock_element_addr, b.status, b.dirty, e.mode_held, e.local 
from v$bh b, v$gc_element e
19:19:15   2  19:19:15   3  where b.file#=5 and b.block#=212
19:19:15   4  and b.lock_element_addr = e.gc_element_addr;

no rows selected


19:19:02 jin@rraw2>select b.lock_element_addr, b.status, b.dirty, e.mode_held, e.local 
19:19:19   2  from v$bh b, v$gc_element e
19:19:19   3  where b.file#=5 and b.block#=212
19:19:19   4  and b.lock_element_addr = e.gc_element_addr;

no rows selected

19:19:19 jin@rraw2>
19:19:05 jin@rraw3>select b.lock_element_addr, b.status, b.dirty, e.mode_held, e.local 
19:19:07   2  from v$bh b, v$gc_element e
19:19:07   3  where b.file#=5 and b.block#=212
19:19:07   4  and b.lock_element_addr = e.gc_element_addr;

no rows selected

##############################################

19:41:54 jin@rraw2>select b.lock_element_addr, b.status, b.dirty, e.mode_held, e.local 
19:41:57   2  from v$bh b, v$gc_element e
19:41:57   3  where b.file#=5 and b.block#=212
19:41:57   4  and b.lock_element_addr = e.gc_element_addr;

LOCK_ELEMENT_ADD STATUS     D  MODE_HELD      LOCAL
---------------- ---------- - ---------- ----------
000000006EFE4660 scur       N          1          1

19:41:57 jin@rraw2>update jin set id = 1 where id =3;

1 row updated.

19:42:31 jin@rraw2>select b.lock_element_addr, b.status, b.dirty, e.mode_held, e.local 
19:42:36   2  from v$bh b, v$gc_element e
19:42:36   3  where b.file#=5 and b.block#=212
19:42:36   4  and b.lock_element_addr = e.gc_element_addr;

LOCK_ELEMENT_ADD STATUS     D  MODE_HELD      LOCAL
---------------- ---------- - ---------- ----------
000000006EFE4660 xcur       Y          2          1


19:42:04 jin@rraw3>select b.lock_element_addr, b.status, b.dirty, e.mode_held, e.local 
19:43:11   2  from v$bh b, v$gc_element e
19:43:11   3  where b.file#=5 and b.block#=212
and b.lock_element_addr = e.gc_element_addr;
19:43:12   4  
no rows selected


19:41:33 jin@rraw1>l
  1  select b.lock_element_addr, b.status, b.dirty, e.mode_held, e.local
  2  from v$bh b, v$gc_element e
  3  where b.file#=5 and b.block#=212
  4* and b.lock_element_addr = e.gc_element_addr
19:43:24 jin@rraw1>/

no rows selected

19:43:25 jin@rraw1>

19:45:43 jin@rraw3>select b.lock_element_addr, b.status, b.dirty, e.mode_held, e.local 
19:45:47   2  from v$bh b, v$gc_element e
where b.file#=5 and b.block#=212
19:45:47   3  19:45:47   4  and b.lock_element_addr = e.gc_element_addr;

LOCK_ELEMENT_ADD STATUS     D  MODE_HELD      LOCAL
---------------- ---------- - ---------- ----------
000000006EFF1AE0 xcur       Y          2          0


19:44:45 jin@rraw2>l
  1  select b.lock_element_addr, b.status, b.dirty, e.mode_held, e.local
  2  from v$bh b, v$gc_element e
  3  where b.file#=5 and b.block#=212
  4* and b.lock_element_addr = e.gc_element_addr
19:45:54 jin@rraw2>/

LOCK_ELEMENT_ADD STATUS     D  MODE_HELD      LOCAL
---------------- ---------- - ---------- ----------
000000006EFE4660 pi         Y          0          0

  1  select b.lock_element_addr, b.status, b.dirty, e.mode_held, e.local
  2  from v$bh b, v$gc_element e
  3  where b.file#=5 and b.block#=212
  4* and b.lock_element_addr = e.gc_element_addr
19:45:54 jin@rraw2>/

LOCK_ELEMENT_ADD STATUS     D  MODE_HELD      LOCAL
---------------- ---------- - ---------- ----------
000000006EFE4660 pi         Y          0          0

19:45:55 jin@rraw2>commit
19:46:41   2  ;

Commit complete.

19:46:42 jin@rraw2>select b.lock_element_addr, b.status, b.dirty, e.mode_held, e.local 
19:46:50   2  from v$bh b, v$gc_element e
19:46:50   3  where b.file#=5 and b.block#=212
19:46:50   4  and b.lock_element_addr = e.gc_element_addr;

LOCK_ELEMENT_ADD STATUS     D  MODE_HELD      LOCAL
---------------- ---------- - ---------- ----------
000000006EFE4660 pi         Y          0          0

19:46:50 jin@rraw2>select * from jin;

        ID
----------
         1
         1

19:47:01 jin@rraw2>select b.lock_element_addr, b.status, b.dirty, e.mode_held, e.local 
19:47:04   2  from v$bh b, v$gc_element e
where b.file#=5 and b.block#=212
and b.lock_element_addr = e.gc_element_addr;
19:47:04   3  19:47:04   4  
LOCK_ELEMENT_ADD STATUS     D  MODE_HELD      LOCAL
---------------- ---------- - ---------- ----------
000000006EFE4660 pi         Y          0          0



19:46:29 jin@rraw3>select b.lock_element_addr, b.status, b.dirty, e.mode_held, e.local 
19:46:34   2  from v$bh b, v$gc_element e
19:46:34   3  where b.file#=5 and b.block#=212
and b.lock_element_addr = e.gc_element_addr;
19:46:34   4  
LOCK_ELEMENT_ADD STATUS     D  MODE_HELD      LOCAL
---------------- ---------- - ---------- ----------
000000006EFF1AE0 xcur       Y          2          0

19:48:12 jin@rraw2>update jin set id = 0 where rownum = 1;

1 row updated.

19:48:24 jin@rraw2>select * from jin;

        ID
----------
         0
         1

19:48:29 jin@rraw2>select b.lock_element_addr, b.status, b.dirty, e.mode_held, e.local 
from v$bh b, v$gc_element e
where b.file#=5 and b.block#=212
19:48:32   2  19:48:32   3  19:48:32   4  and b.lock_element_addr = e.gc_element_addr;

LOCK_ELEMENT_ADD STATUS     D  MODE_HELD      LOCAL
---------------- ---------- - ---------- ----------
000000006EFE4660 xcur       Y          2          1

19:50:32 jin@rraw3>alter system flush buffer_cache;
/
System altered.

19:50:47 jin@rraw3   
19:50:50 jin@rraw3>
19:50:50 jin@rraw3>
19:50:50 jin@rraw3>select * from jin;

        ID
----------
         1
         1

19:50:53 jin@rraw3>select b.lock_element_addr, b.status, b.dirty, e.mode_held, e.local 
19:50:58   2  from v$bh b, v$gc_element e
19:50:58   3  where b.file#=5 and b.block#=212
19:50:58   4  and b.lock_element_addr = e.gc_element_addr;

LOCK_ELEMENT_ADD STATUS     D  MODE_HELD      LOCAL
---------------- ---------- - ---------- ----------
000000006EFF1AE0 xcur       Y          2          1


  1  select b.lock_element_addr, b.status, b.dirty, e.mode_held, e.local
  2  from v$bh b, v$gc_element e
  3  where b.file#=5 and b.block#=212
  4* and b.lock_element_addr = e.gc_element_addr
19:52:52 jin@rraw2>/

no rows selected






##################################################




19:50:32 jin@rraw3>alter system flush buffer_cache;
19:54:16 jin@rraw2>alter system flush buffer_cache;

19:55:02 jin@rraw2>select * from jin;

        ID
----------
         0
         1

19:55:13 jin@rraw2>update jin set id=2 where id = 1;

1 row updated.

19:55:24 jin@rraw2>select b.lock_element_addr, b.status, b.dirty, e.mode_held, e.local 
from v$bh b, v$gc_element e
where b.file#=5 and b.block#=212
19:55:26   2  19:55:26   3  19:55:26   4  and b.lock_element_addr = e.gc_element_addr;

LOCK_ELEMENT_ADD STATUS     D  MODE_HELD      LOCAL
---------------- ---------- - ---------- ----------
000000006EFE4660 xcur       Y          2          1



19:56:14 jin@rraw3>select * from jin;

        ID
----------
         0
         1

19:56:22 jin@rraw3>select b.lock_element_addr, b.status, b.dirty, e.mode_held, e.local 
from v$bh b, v$gc_element e
where b.file#=5 and b.block#=212
and b.lock_element_addr = e.gc_element_addr;
19:56:25   2  19:56:25   3  19:56:25   4  
no rows selected

19:56:25 jin@rraw3>

19:57:01 jin@rraw3>select * from jin;

        ID
----------
         0
         2

19:57:07 jin@rraw3>select b.lock_element_addr, b.status, b.dirty, e.mode_held, e.local 
19:57:08   2  from v$bh b, v$gc_element e
19:57:08   3  where b.file#=5 and b.block#=212
19:57:08   4  and b.lock_element_addr = e.gc_element_addr;

no rows selected


19:57:24 jin@rraw3>select b.lock_element_addr, b.status, b.dirty, e.mode_held, e.local 
from v$bh b, v$gc_element e
where b.file#=5 and b.block#=212
19:57:25   2  19:57:25   3  19:57:25   4  and b.lock_element_addr = e.gc_element_addr;

no rows selected

19:57:25 jin@rraw3>select * from jin;

        ID
----------
         0
         2

19:57:30 jin@rraw3>select * from jin;    

        ID
----------
         0
         2

19:57:33 jin@rraw3>select * from jin;    

        ID
----------
         0
         2

19:57:38 jin@rraw3>select * from jin;    

        ID
----------
         0
         2

19:57:39 jin@rraw3>select * from jin;    

        ID
----------
         0
         2

19:57:40 jin@rraw3>select * from jin;    

        ID
----------
         0
         2

19:57:41 jin@rraw3>select * from jin;    

        ID
----------
         0
         2

19:57:41 jin@rraw3>select * from jin;    

        ID
----------
         0
         2

19:57:42 jin@rraw3>select b.lock_element_addr, b.status, b.dirty, e.mode_held, e.local 
19:57:46   2  from v$bh b, v$gc_element e
19:57:46   3  where b.file#=5 and b.block#=212
19:57:46   4  and b.lock_element_addr = e.gc_element_addr;

LOCK_ELEMENT_ADD STATUS     D  MODE_HELD      LOCAL
---------------- ---------- - ---------- ----------
000000006EFF1AE0 scur       N          1          0





  • 쓰기/읽기 전송: Write to Read Transfer
  1. C노드는 마스터 노드인 B에게 K블록을 SCur 모드로 요청한다.
  2. B노드는 현재 K블록을 A노드가 XCur 모드로 캐싱하고 있음을 확인하고 C노드에게 보내주도록 지시한다.
  3. A노드는 C노드에게 블록을 전송하고 자신일 갖고 있던 블록은 SCur모드로 다운그레이드한다.
  4. C노드는 K블록을 SCur모드로 캐싱하게 됐음을 B노드에게 알려준다. 이때 A노드에 캐싱돼 있던 블록이 SCur모드로 다운그레이드된 사실까지 함께 알려준다.


NODE 2

SQL> /

LOCK_ELEMENT_ADD STATUS                DIR  MODE_HELD      LOCAL
---------------- --------------------- --- ---------- ----------
0000000062FE7C10 xcur                  Y            2          1

NODE 1


SQL> update jin set id = 1 where id=1;     

1 row updated.

SQL> select * from jin;

        ID
----------
         1
         0
         
SQL> /

LOCK_ELEMENT_ADD STATUS                DIR  MODE_HELD      LOCAL
---------------- --------------------- --- ---------- ----------
0000000062BFBB10 xcur                  N            2          0

NODE2

SQL>  select * from jin;

        ID
----------
         1
         0
         

LOCK_ELEMENT_ADD STATUS                DIR  MODE_HELD      LOCAL
---------------- --------------------- --- ---------- ----------
0000000062FE7C10 pi                    Y            0          0

Node1


SQL> select * from jin;

        ID
----------
         1
         0

SQL> commit;

Commit complete

Node 2

SQL> /

no rows selected -> PI -> NULL 


Node 1

SQL> select b.lock_element_addr, b.status, b.dirty, e.mode_held, e.local 
  2  from v$bh b, v$gc_element e
  3  where b.file#=5 and b.block#=654
  4  and b.lock_element_addr = e.gc_element_addr;

LOCK_ELEMENT_ADD STATUS                DIR  MODE_HELD      LOCAL
---------------- --------------------- --- ---------- ----------
0000000062BFBB10 xcur                  Y            2          0


XCur모드 블록을 가지고 있는경우, 이 블록의 커밋여부에 따라 처리가 다르다.
커밋하지 않았으면 Current블록을 보내지 않고 CR Copy를 만들어 전송한다.
커밋되었다면 일정 횟수까지는 CR Copy를 전송하고, 일정 횟수가 넘어가면 Current 블록을 보내준다. CR Copy를 보내는 횟수는 _fairness_threshold 파라미터에 의해 결정됨

Dynamic remastering

  • 리소스 친화도에 따라 마스터 노드가 동적으로 변할 수 있다. 리소스의 OwnerShip은 A가 가지고 있으나, B가 반복적으로 요청한다면, 해당 리소스의 마스터 노드가 B로 변경될 수 있다는 것이다. 자주 사용하는 리소스를 자신이 직접 관리하므로 RAC 성능 향상에 도움을 준다.