ASSM
ASSM(Automatic Segment Space Management)은 FLM과 달리 프리리스트를 사용해 프리 블록을 관리하지 않는다. FLM을 사용하는 경우 프리리스트, 프리리스트 그룹 등의 속성을 이용해 관리자가 수동(Manual)으로 관리 가능한 반면, ASSM을 사용하는 경우에는 더 이상 이러한 속성을 지원하지 않으며 관리자가 세그먼트 공간 관리 기법의 행동 양식을 변경할 수 없다. 이런 의미에서, 즉 수동으로 관리가 불가능하다는 의미에서 자동화된 세그먼트 공간 관리 기법으로 이름이 붙여졌다.
ASSM에서 사용하는 프리 블록 관리 기법은 대단히 복잡하고 지능적이다. 여기서는 중요한 개념과 성능의 관점에서 유리한 점들만을 집중적으로 살펴볼 것이다.
프리 블록의 의미
ASSM에서의 프리 블록의 의미는 FLM에서와 동일하다. 즉, INSERT 작업을 위해 사용 가능한 여유 블록을 의미한다. 하지만 프리 블록을 판단하는 기준은 새롭게 정의되었으며 더욱 세련된 방식의 블록 공간 관리 개념을 사용한다. ASSM에서도 특정 블록이 프리(Free) 상태인지 풀(Full) 상태인지의 구분은 여전히 존재하지만, 블록이 얼마나 여유가 있는지를 판단하는 새로운 기준을 사용한다. 이것을 여유도 상태(Freeness Status. FS)라고 부른다. 여유도 상태는 다음과 같은 네 가지 종류의 값을 지닌다.
- FS1: 블록의 여유 공간이 0~25% 인 상태
- FS2: 블록의 여유 공간이 25~50% 인 상태
- FS3: 블록의 여유 공간이 50~75% 인 상태
- FS4: 블록의 여유 공간이 75~100% 인 상태
블록의 프리 여부는 여전히 PCTFREE 속성 값을 이용해 판단하지만, 프리 블록이 얼마나 여유가 있는지를 다시 FS 값을 이용해 판단하게 된다. 이렇게 함으로써 오라클이 최대한 블록을 효율적으로 사용할 수 있도록 보장한다. 오라클은 PCTFREE 속성과 FS 값을 이용해 다음과 같은 기준으로 프리 블록을 여부를 결정한다.
- 익스텐트가 추가로 할당되는 과정에서 생긴 HWM 아래에 존재하는 한번도 사용되지 않은 블록. FLM에서와 동일하다.
- INSERT 문에 의해 로우(Row)가 추가되었지만, 아직 PCTFREE 속성에 의해 지정된 영역을 다 사용하지 않은 블록. FLM의 경우와 동일하다.
- PCTFREE 속성에 의해 지정된 영역을 다 소모한 후, 다시 DELETE나 UPDATE에 의해 사용률이 낮아지되, FS 상태가 변하는 경우. FLM에서는 풀 블록이 프리 블록으로 바뀌는 기준으로 PCTUSED 속성이 사용되는 반면, ASSM에서는 더 이상 PCTUSED 속성이 사용되지 않는다. ASSM에서는 풀 상태의 블록에서 데이터가 지워지면서 FS의 상태가 바뀌어야만, 가령 FS1(0~25% 여유) 상태에서 FS2(25~50% 여유) 상태로 바뀌는 경우에 다시 프리 블록으로 인식된다. FLM에 비해 블록의 사용 정도를 구분하는 기준이 더욱 세련되어졌음을 알 수 있다.
아래 그림을 보면 ASSM에서 PCTFREE 속성과 FS 값이 어떻게 블록의 프리 여부를 결정하는지 알 수 있다. 그림:Pctfree속성.jpg
오라클이 제공하는 DBMS_SPACE 패키지를 이용하면 세그먼트 공간에 대한 다양한 정보를 얻을 수 있다. 특히DBMS_SPACE.SPACE_USAGE 프로시저를 이용하면 특정 세그먼트의 FS1, FS2, FS3, FS4, Full, Unformatted 상태의 블록 수와 크기(바이트)에 대한 정보를 얻을 수 있다. 다음은 DBMS_SPACE.SPACE_USAGE 프로시저를 사용하는 간단한 예제이다.
DECLARE v_unformatted_blocks NUMBER; v_unformatted_bytes NUMBER; v_fs1_blocks NUMBER; v_fs1_bytes NUMBER; v_fs2_blocks NUMBER; v_fs2_bytes NUMBER; v_fs3_blocks NUMBER; v_fs3_bytes NUMBER; v_fs4_blocks NUMBER; v_fs4_bytes NUMBER; v_full_blocks NUMBER; v_full_bytes NUMBER; BEGIN DBMS_SPACE.SPACE_USAGE( segment_owner =>'OWI', segment_name =>'BIG1', segment_type =>'TABLE', unformatted_blocks => v_unformatted_blocks, unformatted_bytes => v_unformatted_bytes, fs1_blocks => v_fs1_blocks, fs1_bytes => v_fs1_bytes, fs2_blocks => v_fs2_blocks, fs2_bytes => v_fs2_bytes, fs3_blocks => v_fs3_blocks, fs3_bytes => v_fs3_bytes, fs4_blocks => v_fs4_blocks, fs4_bytes => v_fs4_bytes, full_blocks => v_full_blocks, full_bytes => v_full_bytes ); DBMS_OUTPUT.PUT_LINE('v_unformatted_blocks = ' || v_unformatted_blocks); DBMS_OUTPUT.PUT_LINE('v_unformatted_bytes = ' || v_unformatted_bytes); DBMS_OUTPUT.PUT_LINE('v_fs1_blocks = ' || v_fs1_blocks); DBMS_OUTPUT.PUT_LINE('v_fs1_bytes = ' || v_fs1_bytes); DBMS_OUTPUT.PUT_LINE('v_fs2_blocks = ' || v_fs2_blocks); DBMS_OUTPUT.PUT_LINE('v_fs2_bytes = ' || v_fs2_bytes); DBMS_OUTPUT.PUT_LINE('v_fs3_blocks = ' || v_fs3_blocks); DBMS_OUTPUT.PUT_LINE('v_fs3_bytes = ' || v_fs3_bytes); DBMS_OUTPUT.PUT_LINE('v_fs4_blocks = ' || v_fs4_blocks); DBMS_OUTPUT.PUT_LINE('v_fs4_bytes = ' || v_fs4_bytes); DBMS_OUTPUT.PUT_LINE('v_full_blocks = ' || v_full_blocks); DBMS_OUTPUT.PUT_LINE('v_full_bytes = ' || v_full_bytes); END; / v_unformatted_blocks = 0 v_unformatted_bytes = 0 v_fs1_blocks = 0 v_fs1_bytes = 0 v_fs2_blocks = 0 v_fs2_bytes = 0 v_fs3_blocks = 0 v_fs3_bytes = 0 v_fs4_blocks = 0 v_fs4_bytes = 0 v_full_blocks = 237 v_full_bytes = 1941504
3단계 비트맵 블록
ASSM을 사용하는 세그먼트는 프리 블록들의 목록을 관리하기 위해 더 이상 프리리스트(Freelist)를 사용하지 않는다. 대신 3단계의 비트맵 블록(Bitmap Block)을 이용해서 보다 효율적이고 입체적으로 세그먼트 공간을 관리한다. 아래 그림에 3 단계의 비트맵 블록과 프리 블록과의 관계가 표현되어 있다. 그림:비트맵블록.jpg
L1BMB(Level 1 Bitmap Block)는 각 블록의 여유도 상태(Freeness Status. FS)를 관리하는 역할을 한다. 하나의 L1BMB가 세그먼트의 크기에 따라 16 ~ 1,024 개의 블록의 상태를 관리한다. 아래 예제는 필자의 시스템에서 하나의 L1BMB를 덤프로 내려 받은 것으로, 총 64 개의 블록의 상태를 관리하는 것을 확인할 수 있다. 블록의 상태는 “Unformatted, FULL, 0-25% free, 25-50% free, 50-75% free, 75-100% free” 중 하나의 값이 된다.
-------------------------------------------------------- DBA Ranges : L1BMB가 관리하는 블록의 목록들 -------------------------------------------------------- 0x01804109 Length: 64 Offset: 0 0:Metadata 1:Metadata 2:Metadata 3:Metadata 4:Metadata 5:Metadata 6:Metadata 7:Metadata 8:Metadata 9:Metadata 10:Metadata 11:Metadata 12:Metadata 13:Metadata 14:Metadata 15:Metadata 16:Metadata 17:Metadata 18:Metadata 19:Metadata 20:Metadata 21:Metadata 22:FULL 23:FULL 24:FULL 25:FULL 26:FULL 27:FULL 28:FULL 29:FULL 30:FULL 31:FULL 32:FULL 33:FULL 34:FULL 35:FULL 36:FULL 37:FULL 38:FULL 39:FULL 40:FULL 41:FULL 42:FULL 43:FULL 44:FULL 45:FULL 46:FULL 47:FULL 48:FULL 49:FULL 50:FULL 51:FULL 52:FULL 53:FULL 54:FULL 55:FULL 56:FULL 57:FULL 58:FULL 59:FULL 60:FULL 61:FULL 62:FULL 63:FULL --------------------------------------------------------
L2BMB(Level 2 Bitmap Block)는 L1BMB의 목록을 관리한다. 하나의 L2BMB가 여러 개의 L1BMB를 관리하게 된다. 아래 예제는 하나의 L2BMB를 덤프로 내려 받은 것으로, 총 20개의 L1BMB를 관리하고 있는 것을 알 수 있다.
-------------------------------------------------------- 0x01804109 Free: 1 Inst: 1 0x0180410a Free: 1 Inst: 1 0x0180410b Free: 1 Inst: 1 0x0180410c Free: 1 Inst: 1 0x0180410d Free: 5 Inst: 1 0x0180410e Free: 5 Inst: 1 0x0180410f Free: 5 Inst: 1 0x01804110 Free: 5 Inst: 1 0x01804111 Free: 5 Inst: 1 0x01804112 Free: 5 Inst: 1 0x01804113 Free: 5 Inst: 1 0x01804114 Free: 5 Inst: 1 0x01804115 Free: 5 Inst: 1 0x01804116 Free: 5 Inst: 1 0x01804117 Free: 5 Inst: 1 0x01804118 Free: 5 Inst: 1 0x01804119 Free: 5 Inst: 1 0x0180411a Free: 5 Inst: 1 0x0180411b Free: 5 Inst: 1 0x0180411c Free: 5 Inst: 1 --------------------------------------------------------
L2BMB는 L1BMB에 대해서 다음과 같은 정보를 관리한다.
- L1BMB DBA
- L1BMB가 관리하는 블록들의 최대 여유도(Maximum Freeness). 1=Full, 2=FS1, 3=FS2, 4=FS3, 5=FS4를 의미한다. 오라클은 공간의 효율성을 높이기 위해 가장 여유도가 높은 L1BMB를 먼저 사용한다.
- 소유 인스턴스(Owning Instance). RAC 환경에서 해당 L1BMB를 소유한 인스턴스의 번호를 의미한다. RAC 환경에서는 이 정보를 이용해서 인스턴스 간에 프리 블록을 둘러싼 경합을 최소화한다. ASSM에서 프리리스트 그룹(Freelist Group) 기능이 사라진 이유가 여기에 있다.
L3BMB는 L2BMB의 목록을 관리한다. 하나의 L3BMB가 여러 개의 L2BMB를 관리할 수 있다. L3BMB는 대부분의 경우 별도의 물리적인 블록으로 존재하지 않고, 세그먼트 헤더 블록 내부에 존재한다. 세그먼트의 크기가 매우 커서 하나의 L3BMB로 관리가 불가능할 때에만 별도의 L3BMB가 물리적으로 분리된다. 아래 예제는 L3BMB(세그먼트 헤더)를 덤프로 내려 받은 것으로, L2BMB에 대한 부가적인 정보(L2 Hint for inserts)와 L2BMB의 DBA 값을 확인할 수 있다.
Segment Type: 1 nl2: 1 blksz: 8192 fbsz: 0 L2 Array start offset: 0x00001434 First Level 3 BMB: 0x00000000 L2 Hint for inserts: 0x0180411d Last Level 1 BMB: 0x0180411c Last Level II BMB: 0x0180411d Last Level III BMB: 0x00000000 … Second Level Bitmap block DBAs -------------------------------------------------------- DBA 1: 0x0180411d
오라클은 L3BMB, L2BMB, L1BMB를 순차적으로 탐색하면서 새로운 데이터를 추가할 가장 이상적인 프리 블록을 찾는다. ASSM에서 사용하는 3단계의 비트맵 블록 구조는 이전 프리리스트 구조에 비해 상당히 유연하고 자동화되어 있어서, FLM을 사용할 때와 같은 외부적인 튜닝이나 설정이 불필요하다. 성능 또한 잘 튜닝된 FLM을 사용할 때와 거의 비슷하다. 다만 대량의 DML이 발생하는 경우, 비트맵 블록을 관리하기 위한 오버헤드가 발생하기 때문에 이로 인한 약간의 성능 저하가 발생할 수 있다.
RAC와 ASSM
ASSM은 RAC를 위한 세그먼트 관리 기법이라고 해도 무방할 정도로 RAC 환경에 최적화되어 있다. ASSM이 제공하는 다음과 같은 특징을 보면 오라클이 RAC에 최적화된 세그먼트 관리 기법을 제공하기 위해 노력한 흔적을 찾아볼 수 있다.
- L1BMB의 리소스 친화도: L1BMB가 처음 생성될 때 RAC 시스템 중 어느 인스턴스가 이 블록에 대한 소유권을 가질 지를 결정한다. 즉 L1BMB는 리소스 친화도를 갖도록 설계되었다. 서로 다른 인스턴스는 서로 다른 L1BMB를 사용하게 되므로 프리 블록을 둘러싼 경합이 최소화된다. FLM에서의 프리리스트 그룹 기능과 거의 비슷한 효과를 제공하는 셈이다. 프리리스트 그룹 기능은 수동적인 설정이 필요하고 클러스터의 멤버들이 변하는 상황에 대해 적응력이 매우 낮다는 점을 고려하면 ASSM의 우수성을 깨닫게 될 것이다.
- L1BMB 훔치기: L1BMB는 리소스 친화도를 가지고 있기 때문에 특정 인스턴스에 속하게 된다. 이것은 일반적으로 바람직한 기능이지만 만일 특정 인스턴스가 특정 L1BMB를 계속해서 점유한다면 데이터 비대칭(Data Skew) 현상이 생길 수 있다. 데이터 비대칭이란 특정 인스턴스가 세그먼트의 특정 부분을 독점함으로써 다른 인스턴스가 해당 부분을 전혀 사용할 수 없게 되는 현상을 의미한다. FLM에서 프리리스트 그룹을 사용하는 경우 데이터 비대칭 현상이 발생할 수 있다는 것은 앞서 언급한 바 있다. ASSM에서는 데이터 비대칭 현상을 원천적으로 피하기 위해 L1BMB 훔치기(BMB Stealing) 기능을 제공한다. L1BMB 훔치기 기능은 말 그대로 다른 인스턴스가 소유한 L1BMB를 훔쳐서 사용하는 기능을 말한다. 오라클은 세그먼트 공간 사용 요구 정도가 지나치게 많다고 판단되면 다른 인스턴스가 소유한 L1BMB를 훔쳐와서 사용한다. 특정 인스턴스가 클러스터에서 빠져 나간 경우에도 해당 인스턴스가 소유한 L1BMB는 다른 인스턴스에 의해 훔쳐진다. 엄격한 리소스 친화도가 아닌 필요에 따라 소유 인스턴스가 변할 수 있다는 의미에서 이러한 기능을 약 친화도(Soft Affinity)라고 부르기도 한다. 즉 L1BMB는 약 친화도를 가지며 이를 통해 FLM에서 문제가 되었던 데이터 왜곡 현상을 원천적으로 방지한다.
다시 한번 정리하면, ASSM의 공간 관리 기법은 RAC 시스템에서 각 인스턴스간의 프리 블록 경합을 최소화할 수 있도록 설계되었으며, 이로 인해 INSERT 작업 시 노드 간의 경합이 최소화된다.
ASSM과 비트맵 블록 경합
ASSM이 FLM에 비해 여러 가지 뛰어난 장점을 제공하지만 대량의 DML이 발생하는 상황에서는 오버헤드가 발생할 수 있다. 아이러니한 것은 FLM의 단점을 제거하기 위해 설계된 3단계의 비트맵 블록으로 인해 이러한 오버헤드가 발생한다는 것이다.
L1BMB는 개별 블록들의 여유도 상태(Freeness Status)를, L2BMB는 개별 L1BMB들의 상태를, L3BMB는 개별 L2BMB들의 상태를 관리한다. 만일 개별 블록들의 여유도 상태가 변경되면 L1BMB에 대한 변경(Update) 작업이 발생한다. L1BMB의 상태가 변경되면 L2BMB에 대한 변경 작업이 발생한다. 마지막으로 L2BMB의 상태가 변경되면 L3BMB에 대한 변경 작업이 발생한다. 대량 DML이 발생하는 경우 비트맵 블록의 변경이 빈번하게 발생할 수 있다. 특히 L1BMB와 L2BMB에 대한 변경 작업이 많이 발생하게 되며 이로 인해 약간의 성능 저하가 발생할 수 있다. 만일 동시에 여러 세션이 동일 세그먼트에 대해 INSERT를 수행한다면, L1BMB와 L2BMB를 동시에 변경하게 되고 이로 인해 buffer busy waits이벤트에 대해 대기시간이 증가한다. 이 경우 블록 클래스(Class#)는 8번(L1BMB) 또는 9번(L2BMB)로 관찰된다.
ASSM에서 비트맵 블록의 경합에 의해 약간의 성능 저하 현상이 발생하지만, 이것은 ASSM이 제공하는 다른 많은 장점들에 의해 상쇄된다. 특히 RAC 환경에서는 어떤 이유를 막론하고 FLM이 아닌 ASSM을 사용하는 것이 좋다. 만일 굳이 FLM을 사용한다면 프리리스트 그룹을 노드 수와 동일하게 부여해야 한다. 하지만 FLM을 사용하는 경우 데이터 비대칭 현상을 피할 수 없다는 사실에 주의해야 한다.
ASSM과 FB 락 경합
ASSM을 사용하는 세그먼트에 대한 대량 DML 작업 시에 FB 락 경합이 발생하는 경우가 종종 발생한다. FB 락은 Formatting Block Lock을 의미한다. FB 락의 의미를 이해하려면 ASSM을 사용하는 세그먼트에는 두 개의 HWM(High Water Mark)가 존재한다는 사실을 이해할 필요가 있다. ASSM에서는 하나의 익스텐트가 여러 개의 L1BMB에 의해 나누어 관리될 수 있다. 만일 특정 익스텐트의 앞 부분과 뒤 부분은 L1BMB에 의해 관리되고, 중간 부분은 아직 L1BMB가 할당되지 않았다면 중간에 구멍(Hole)이 생기게 된다. 즉 세그먼트의 중간 중간에 전혀 사용되지 않는 비 포맷 상태의 블록들이 다수 존재할 수 있다. 이러한 현상은 FLM에서는 찾아볼 수 없는 ASSM만의 고유한 공간 관리 기법에 의해 초래된다. 이러한 이유로 오라클은 Low HWM과 High HWM 이라는 두 개의 HWM을 관리한다. Low HWM 이하의 블록들은 모두 포맷 상태의 블록으로 “현재 사용 중”인 블록들이다. High HWM 이상의 블록들은 모두 비 포맷 상태의 블록이며, “아직 사용되지 않은” 블록들이다. Low HWM과 High HWM 사이에는 아직 사용되지 않은 비 포맷 상태의 블록들이 존재할 수 있다. 이러한 비 포맷 상태의 블록들은 추후에 INSERT 작업에 의해 사용되는 시점에 포맷되며 이 과정에서 FB 락을 획득한다. 많은 수의 프로세스들이 동시에 같은 영역의 비 포맷 블록을 사용하고자 하는 경우 FB 락 경합이 발생하게 되고, enq: FB – contention 이벤트에 대한 대기로 관찰된다. FB 락 경합은 ASSM 환경에서는 피할 수 없는 현상이며, 성능에 주는 영향도 미미하다. 아래 샘플은 세그먼트 헤더 블록에 대한 덤프 파일로 세그먼트 헤더 블록 내에서 Low HWM과 High HWM을 같이 관리하는 것을 확인할 수 있다.
Start dump data blocks tsn: 7 file#: 6 minblk 16670 maxblk 16673 buffer tsn: 7 rdba: 0x0180411e (6/16670) scn: 0x0000.00472a3d seq: 0x01 flg: 0x04 tail: 0x2a3d2301 frmt: 0x02 chkval: 0x7e6e type: 0x23=PAGETABLE SEGMENT HEADER Hex dump of block: st=0, typ_found=1 … Extent Control Header ----------------------------------------------------------------- Extent Header:: spare1: 0 spare2: 0 #extents: 1 #blocks: 1280 last map 0x00000000 #maps: 0 offset: 2716 Highwater:: 0x0180420c ext#: 0 blk#: 259 ext size: 1280 #blocks in seg. hdr's freelists: 0 #blocks below: 259 mapblk 0x00000000 offset: 0 Unlocked -------------------------------------------------------- Low HighWater Mark : Highwater:: 0x0180420c ext#: 0 blk#: 259 ext size: 1280 #blocks in seg. hdr's freelists: 0 #blocks below: 259 mapblk 0x00000000 offset: 0 Level 1 BMB for High HWM block: 0x0180410d Level 1 BMB for Low HWM block: 0x0180410d …
아래 스크립트는 ASSM을 사용하는 세그먼트에 대해 동시 다발적인 대량 INSERT 작업을 수행하는 경우에 어떤 종류의 경합들이 발생하는지를 테스트한 결과로, HW 락 경합, 버퍼 락 경합, FB 락 경합 등이 주로 목격되는 것을 알 수 있다.
-- ASSM을 사용하는 테이블 스페이스 생성 create tablespace fb_tbs1 datafile '/home/oracle/oradata/10gr2/ORA102/fb_tbs1.dbf' size 10M autoextend on segment space management auto extent management local uniform size 5M -- 테이블 생성(1로우 = 1블록) create table fb_table1(id number, name1 char(2000) default 'a', name2 char(2000) default 'a', name3 char(2000) default 'a', name4 char(1500) default 'a') tablespace fb_tbs1; -- FB_TABLE1에 500건을 추가하는 프로시저 create or replace procedure fb_insert is begin for idx in 1 .. 500 loop insert into fb_table1(id) values(idx); end loop; end; -- 동시에 20개의 세션에서 SQL*Trace를 활성화시킨 상태에서 FB_INSERT 프로시저를 수행하고, trcsess 툴을 이용해서 20개의 세션이 남긴 트레이스 파일을 병합한 뒤 tkprof 툴을 이용해 대기회수와 시간 정보 추출한 결과는 다음과 같다. INSERT INTO FB_TABLE1(ID) VALUES (:B1 ) Call count cpu elapsed disk query current rows ----- ------ ----- ------ ----- ---- ------ ---- Parse 21 0.00 0.02 0 0 0 0 Execute 10500 17.22 605.20 0 20176 100188 10500 Fetch 0 0.00 0.00 0 0 0 0 ------ ------ ----- ------ ----- ---- ------ ---- Total 10521 17.22 605.22 0 20176 100188 10500 Misses in library cache during parse: 1 Misses in library cache during execute: 1 Optimizer mode: ALL_ROWS Parsing user id: 55 (recursive depth: 1) Elapsed times include waiting on following events: Wait Event Total Total Time Waited Timeout Waited ------------------------------ ------- ------- -------- enq: HW ? contention 1364 2.82 348.29 latch: In memory undo latch 4 0.00 0.00 enq: FB ? contention 1692 0.17 9.71 buffer busy waits 9276 0.29 100.79 latch: redo copy 522 0.14 1.68 latch free 108 0.01 0.41 latch: cache buffers chains 359 0.22 2.06 enq: TX ? contention 270 2.63 4.07 log buffer space 656 0.29 55.26 latch: redo allocation 20 0.00 0.02 latch: enqueue hash chains 74 0.09 1.61 wait list latch free 9 0.02 0.21 cursor: pin S 9797 0.00 0.00 latch: undo global data 11 0.02 0.09 …
HW 락 경합은 세그먼트 확장에 따라 HWM을 이동하는 과정에서 발생하면 enq: HW – contention 이벤트 대기로 관찰된다. FB 락 경합은 Low HWM과 High HWM 사이의 구멍(Hole)에 해당하는 블록을 포맷하는 과정에서 발생하며 enq: FB – contention 이벤트에 대기로 관찰된다. 버퍼 락 경합은 블록들의 여유도 상태가 변경됨에 따라 비트맵 블록의 정보를 변경하는 과정에서 발생하며 블록 클래스 값이 8 또는 9인 buffer busy waits 이벤트에 대한 대기로 관찰된다. FLM을 사용하는 경우에는 FREELISTS 속성이나 FREELIST GROUPS 속성, 혹은 _BUMP_HIGHWATER_MARK_COUNT 파라미터 값을 변경함으로써 이러한 경합들에 대한 튜닝이 가능했지만, ASSM에서는 이러한 외부적인 튜닝을 할 수 없다. 따라서 문제가 발생한 원인을 바탕으로 어플리케이션의 작동 방식을 개선하는 방식의 튜닝 접근법을 따라야 한다.
추가 설명 :
출처 : http://shocky00.springnote.com/pages/990322
8i까지에서, segment의 free block들은 항상 freelist를 통해 관리된다. PCTUSED아래로 채워진 block들이 freelist로 연결되어 있어서, insert가 필요하면 이 freelist를 segment header에서부터 뒤지면서 블럭내의 빈 공간에 insert를 하게 되는것이다. 9i에서 제시된 이 ASSM방식은 segment에 할당된 space를 bitmap으로 관리한다. auto가 아닌 manual로 지정되게 되면 이전과 같이 freelist방식을 사용하게 되며, DBA_TABLESPACES view의 SEGMENT_SPACE_MANAGEMENT column을 통해 AUTO인지 MANUAL방식인지 확인 가능하다. 이렇게 ASSM 방법을 이용하여 space를 관리하게 되면 free block에 대해서 좀 더 상세한 정보를 바탕으로 space utilization도 높아지고, freelist를 타고 다음다음 block을 access하는대신 BMB를 참고로 적당한 block들을 선택하기 때문에 space에 관한 성능도 좋아진다. ASSM방식을 사용하지 않고 freelist방법을 사용하는 경우 segment에 할당된 extent 내에 free block을 확인하는 방법은, table analyze후 DBA_TABLES의 EMPTY_BLOCK를 확인하거나 DBMS_SPACE.UNUSED_SPACE procedure를 이용하는 방법이 존재한다. 그리고 이 두 가지는 같은 정보를 보여준다. 이때, FS1 ~ FS4가 의미하는것은 다음과 같다. 이예에서 SCOTT user의 TEST table에 data를 insert시키고 analyze후 조회하니 다음과 같은 결과가 나왔다. (단, DBMS_SPACE.SPACE_USAGE사용을 위해서는 analyze를 수행할 필요가 없다.) DBA_TABLES DBMS_SPACE.UNUSED_SPACE DBMS_SPACE.SPACE_USAGE 10 3 13 0 1 9 Reference Documents <Note:180608.1> Automatic Space Segment Management in RAC Environments <Note:149516.1> BMB versus Freelist Segment: DBMS_SPACE.UNUSED_SPACE and DBA_TABLES.EMPTY_BLOCKS1. freelist를 통한 free block관리
같은 table에 대해서 insert 트랜잭션이 동시에 많은 경우 table storage의 freelists 값을 증가시켜야 하고, OPS의 경우 node갯수를 고려하여 freelist groups을 지정해야 하는 등 freelist와 관련하여 DB Admin이 고려하여야 할 tuning point가 존재하여 왔다.
또한 이 freelist내의 free block에 대한 정보가 segment header내에 전체 정보를 가지고 있거나 dictionary table에 정보를 가지고 있는 것이 아니고, linked list 형태로 free block이 다음 free block을 지정하는 형태라 쉽게 freelist에 대한 정보를 확인하는 것도 불가능하다.
이렇게 전체 freelist에 대한 정보를 쉽게 확인하지 못하는 이유로, table에 대한 reorganization을 결정하는 기준을 정하기도 쉽지 않았고, db내에서 space 활용도 최적이 되지 못한다.
이러한 space관리에 대한 문제점을 극복하기 위해 9i에서 제시된 것이 ASSM (automatic space segment management)이다.2. Automatic Space Segment Management
ASSM 방식을 이용하려면 반드시 locally managed tablespace여야 하며, 다음과 같이 'segment space management auto'를 지정하면된다.
DATAFILE '/oracle/data/data01.dbf' SIZE 50M
EXTENT MANAGEMENT LOCAL
SEGMENT SPACE MANAGEMENT AUTO;
이렇게 생성된 tablespace내에 table이나 index를 생성하게 되면 segment header 외에 추가적인 BMB (BitMap Blocks)라는 것이 생기게 된다. 이 BMB에는 할당된 block들의 space정보를 4 bit를 이용하여 다음 6가지 상태를 나타내는 bitmap 정보를 가진다.
(2) 50% 이상 75% 미만의 free space를 가지는 block
(3) 25% 이상 50% 미만의 free space를 가지는 block
(4) 25% 미만의 free space를 가지는 block
(5) 꽉 찬 block
(6) 한번도 사용하지 않아 format 되지 않은 block
또한 ASSM의 경우 해당 tablespace에 생성된 segment들은 freelists, freelist groups, pctused등은 지정하여도 무시되는데, 이것은 space관리 작업을 단순화시킬뿐 아니라, 특히 freelist groups 지정이 성능에 영향을 미쳤던 RAC에서 큰 도움이 된다. 그외에도 BMB를 동시에 다른 트랜잭션이 다른 part를 access 하는 것 또한 성능에 도움을 준다. 오라클은 internal benchmark 자료에 따르면 RAC에서 최적화된 freelist 관련 parameter를 지정한 상태에서 3백만건 데이타 insert 작업에 대해서, ASSM과 일반 manual 방법을 비교해 본 결과 35 % 정도 ASSM사용이 성능향상에 도움이 되었다.
이때 주의할 점은, locally managed tablespace와 이 ASSM 방식간에 혼동을 일으키는 경우가 종종 있다. 이것은 locally managed tablespace와 ASSM이 둘 다 bitmap방식을 통해 space를 관리한다는 측면때문 일 것으로 보인다.
ASSM방식을 사용하려면 미리 이야기한대로 locally managed tablespace에서만 사용가능한데, 기본적으로 locally managed tablespace는 dba_free_space에서 확인되는 할당되지 않은 space에 대한 관리이고, ASSM은 일단 segment내에 할당된 extent안에서 block내의 free space에 관한 것이다.
locally managed tablespace에 관한 좀 더 자세한 사항은 <Bulletin No: 11860>이나 <Bulletin No: 18261>를 참조하도록 한다.3. space정보 확인 방법
ASSM으로 관리되는 table이나 index에 대해서는 DBA_TABLES의 EMPTY_BLOCKS와 DBMS_SPACE.UNUSED_SPACE가 다른 값을 나타낼 뿐 아니라, ASSM의 정확한 정보를 모두 나타내지 못하므로 새로이 소개된 DBMS_SPACE.SPACE_USAGE procedure를 이용하면 된다.
이 세가지 방법이 나타내는 각 정보에 대해서 자세히 살펴본다.
먼저 DBMS_SPACE.SPACE_USAGE의 사용방법이다. 아래에 예로 SCOTT user의 TEST table에 대해서 예로 들었다. TEST table은 ASSM 방식으로 관리되는 table이다.
2 v_unformatted_blocks number;
3 v_unformatted_bytes number;
4 v_fs1_blocks number;
5 v_fs1_bytes number;
6 v_fs2_blocks number;
7 v_fs2_bytes number;
8 v_fs3_blocks number;
9 v_fs3_bytes number;
10 v_fs4_blocks number;
11 v_fs4_bytes number;
12 v_full_blocks number;
13 v_full_bytes number;
14 begin
15 dbms_space.space_usage ('SCOTT', 'TEST', 'TABLE', v_unformatted_blocks,
16 v_unformatted_bytes, v_fs1_blocks, v_fs1_bytes, v_fs2_blocks,
17 v_fs2_bytes, v_fs3_blocks, v_fs3_bytes, v_fs4_blocks,
18 v_fs4_bytes, v_full_blocks, v_full_bytes);
19 dbms_output.put_line('Unformatted Blocks = '||v_unformatted_blocks);
20 dbms_output.put_line('FS1 Blocks = '||v_fs1_blocks);
21 dbms_output.put_line('FS2 Blocks = '||v_fs2_blocks);
22 dbms_output.put_line('FS3 Blocks = '||v_fs3_blocks);
23 dbms_output.put_line('FS4 Blocks = '||v_fs4_blocks);
24 dbms_output.put_line('Full Blocks = '||v_full_blocks);
25 end;
26 /
FS2 Blocks = 0
FS3 Blocks = 0
FS4 Blocks = 1
Full Blocks = 9
FS2 : 25-50%의 free space를 가진 block
FS3 : 50-75%의 free space를 가진 block
FS4 : 75-100%의 free space를 가진 block
아래의 예에서 보면 첫번째로 DBA_TABLES의 EMPTY_BLOCKS와 DBMS_SPACE.UNUSED_SPACE에서 보여주는 값이 서로 다르다. 그리고 정확한 정보를 주는 DBMS_SPACE_SPACE_USAGE에서는 75%이상 비어있는 block이 한개, full인 block이 9개로 나타난다. 그럼 전체 13개의 block중 3개의 block은 어떠한 block 일까? 이 3개의 BLOCK을 DBA_TALES에서는 EMPTY_BLOCK로 분류하였다.
이 세개의 block는 바로 space를 bitmap으로 관리하는 BMB 들이다.
--------------------- ---------------------------- ------------------------
BLOCKS | EMPTY_BLOCKS TOTAL_BLOCKS | UNUSED_BLOCKS FS4 Blocks | Full Blocks
--------------------- ---------------------------- ------------------------
-------------------