# CACHE FUSION
l RAC 환경에서 데이터 전송
- GRD(Shared pool에 존재) : 내가 찾고자 하는 데이터 버퍼가 어느 노드에 있고 어느 스토리지에 있는지 위치정보와 락정보가 들어있는 공간
n Cache fusion 테스트를 위한 환경구성
SQL#1> create table rac_test ( id number ); 2 SQL#1> insert into rac_test values(1); SQL#1> commit; SQL#1> select dbms_rowid.rowid_relative_fno(rowid) as fno, dbms_rowid.rowid_block_number(rowid) as blkno from rac_test; 2 3 - rac_test 테이블의 file 번호와 block 번호 알아낸다 FNO BLKNO ---------- ---------- 5 3495
SQL#1> select b.lock_element_addr, b.status, e.mode_held from v$bh b, v$gc_element e where b.file#=5 and b.block#=3495 and b.lock_element_addr=e.gc_element_addr; - file과 block에 파일 번호와 블락번호를 넣어준다 LOCK_ELE STATUS MODE_HELD -------- ------- ---------- 22BECBB8 xcur 2 - no row select : null - scur : shared - xcur : exclusive |
l Cache fusion
1. master node : 찾고자 하는 최신 데이터의 정보를(위치정보, 락정보) 알고 있는 노드
2. holder node : 실제로 데이터를 가지고 있는 노드
3. 락정보
- null mode : 데이터를 올리기 위해서 메모리에 공간에 거는 락
- shared mode : 읽기 목적으로 거는 락
- exclusive mode : 쓰기 목적으로 거는 락
l Cache fusion 예제 6가지
1. Initial read with no transfer
- 초기에만 데이터를 읽고 전송하지 않았다는 의미
- instance 1은 처음에 null mode 락으로 공간을 확보한 상태에서 마스터에게 데이터를 요청하고 그 이후에 데이터를 넘겨주고 shared mode로 바뀐다
2. Read to Read with transfer
- inst3번은 필요한 데이터를 가져오기 위해서 null mode로 락을 건다
- inst3번이 block을 요청하고 master는 최신버전이 inst1이 가지고 있고 shared mode로 가지고 있다고 라는 것을 알고 있다.
- 이후에 matser는 inst1에게 데이터를 요청하고 inst1은 inst3에게 데이터를 전달한다
n Read to read with transfer test 테스트
# 2번노드 SQL#2> select * from rac_test; ID ---------- 1
SQL#2> select b.lock_element_addr, b.status, e.mode_held from v$bh b, v$gc_element e where b.file#=5 and b.block#=3495 and b.lock_element_addr=e.gc_element_addr; LOCK_ELE STATUS MODE_HELD -------- ------- ---------- 223F41F8 scur 1
# 1번노드 SQL#1> select b.lock_element_addr, b.status, e.mode_held from v$bh b, v$gc_element e where b.file#=5 and b.block#=3495 and b.lock_element_addr=e.gc_element_addr; LOCK_ELE STATUS MODE_HELD -------- ------- ---------- 22BECBB8 scur 1 |
3. Read to write with transfer
- read to write with transfer의 의미는 전송을 통해서 read 한 데이터를 가지고 데이터를 write 하겠다는 것이다
- update 문장은 row에 락도 걸기 때문에 select문에 비해서 리소스를 많이 사용한다
- inst1에서 update를 요청하고 마스터는 inst3에게 요청하고 inst3은 inst1에게 데이터를 전달한다
- 이후에 값비싼 비용을 치르고 update 했기 때문에 이 데이터는 중요한 정보라고 생각한다. 그래서 exlusive lock을 걸어 업데이트한다
n read to write with transfer test 테스트
# 1번노드 SQL#1> alter system flush shared_pool; SQL#1> alter system flush buffer_cache; SQL#1> update rac_test set id=7 where id=1; SQL#1> commit;
SQL#1> select b.lock_element_addr, b.status, e.mode_held from v$bh b, v$gc_element e where b.file#=5 and b.block#=3495 and b.lock_element_addr=e.gc_element_addr; LOCK_ELE STATUS MODE_HELD -------- ------- ---------- 22BECBB8 xcur 2 - update를 수행한 노드에서 exclusive가 된 것을 확인할 수 있다
# 2번노드 SQL#2> select b.lock_element_addr, b.status, e.mode_held from v$bh b, v$gc_element e where b.file#=5 and b.block#=3495 and b.lock_element_addr=e.gc_element_addr; no rows selected - update를 수행한 노드 이외의 모든 노드는 null mode로 된다 - 왜냐하면 나머지 노드는 최신 정보가 아니기 때문이다 |
4. Write to read with transfer(commit 이후)
- inst1은 update 이후에 exclusive mode이기 때문에 데이터를 가져간 inst3에 null mode 락을 걸도록 만든다
- 다른 경우에는 shared mode로 변경이 됐지만 이 경우에는 update라는 비싼 비용을 치르고 수행한 update는 exclusive mode로 락을 걸고 다른 inst3은 null mode 락을걸고 받은 데이터를 받자마자 없앤다
- 그 이후에도 inst3이 4번이상 데이터를 요청하면 데이터를 전달하고 exclusive mode에서 share moded mode로 둘다 바뀐다
- 최종적으로 마스터는 최신정보는 inst1과 inst3 둘다 가지고 있다는 것을 갱신한다
n write to read with transfer 테스트(commit 이후)
# 2번노드 SQL#2> select * from rac_test; SQL#2> select * from rac_test; SQL#2> select * from rac_test; SQL#2> select * from rac_test; SQL#2> select * from rac_test; SQL#2> select b.lock_element_addr, b.status, e.mode_held from v$bh b, v$gc_element e where b.file#=5 and b.block#=3495 and b.lock_element_addr=e.gc_element_addr; LOCK_ELE STATUS MODE_HELD -------- ------- ---------- 223F41F8 scur 1
# 1번모드 SQL#1> select b.lock_element_addr, b.status, e.mode_held from v$bh b, v$gc_element e where b.file#=5 and b.block#=3495 and b.lock_element_addr=e.gc_element_addr; LOCK_ELE STATUS MODE_HELD -------- ------- ---------- 22BECBB8 scur 1
- 노드 1번(exclusive mode),2번(null mode) 둘다 shared mode로 변경된 것을 확인할 수 있다 |
5. Write to read with transfer(commit 이전)
- CR copy : update를 해서 만약에 5000을 8000으로 변경했는데 commit을 안했다면 CR copy를 통해서 rollback buffer에 저장했다가 요청이 들어오면 5000의 값을 rollback buffer 에서 전달한다
- 그런데 checkpoint가 일어나면 DB의 undo에 데이터를 저장한다. checkpoint 이후에는 init3이 데이터를 요청하면 undo에서 데이터를 전달받는다
- commit을 안했다면 init3이 4번이상 요청해도 null mode로 lock이 걸리고 계속 전달받아야 한다
- 이처럼 RAC 환경에서는 commit을 했는지 안했는지에 따라서 차이가 크다
n write to read with transfer 테스트(commit 이전)
# 1번모드 SQL#1> update rac_test set id=5; SQL#1> select b.lock_element_addr, b.status, e.mode_held from v$bh b, v$gc_element e where b.file#=5 and b.block#=3495 LOCK_ELE STATUS MODE_HELD -------- ------- ---------- 22BECBB8 xcur 2
# 2번모드 SQL#2> select * from rac_test; SQL#2> select b.lock_element_addr, b.status, e.mode_held from v$bh b, v$gc_element e where b.file#=5 and b.block#=3495 and b.lock_element_addr=e.gc_element_addr; no rows selected - 몇 번을 수행해도 commit하기 전까지는 null mode이다 |
6. Write to write with transfer
- init3이 데이터를 업데이를 요청하고 exclusive 상태이던 inst1에게 데이터를 요청한다.
- 그 이후에 inst1이 inst3에게 데이터를 전달하고 inst3은 exclusive 상태가 되고 inst1은 상대적으로 null mode로 전환된다
'빅데이터과정 > RAC' 카테고리의 다른 글
#46_140818_RAC_GLOBAL ENQUEUE WAITS (0) | 2014.08.18 |
---|---|
#45_140814_RAC_GC EVENT (0) | 2014.08.14 |
#44_140813_RAC_TUNING (0) | 2014.08.13 |
#44_140813_RAC_DATAFILE 복구 (0) | 2014.08.13 |
#43_140812_RAC_전자지갑 (0) | 2014.08.12 |