세그먼트 (segment)

  • 오라클의 세그먼트(segment)는 디스크 저장공간을 사용하는 객체다.


세그먼트의 일반적인 유형

클러스터 (Cluster)
  • 클러스터 테이블을 저장하는 세그먼트.
  • B*Tree 방식과 해시 방식이 존재한다.


테이블 (Table)
  • 테이블을 위한 세그먼트.
  • 인덱스 세그먼트와 함께 가장 일반적인 세그먼트 유형이다.


테이블 파티션/서브파티션 (Table partition or subpartition)
  • 파티션된 테이블 데이터를 저장하는 세그먼트.


인덱스 (Index)
  • 인덱스 구조를 저장하는 세그먼트.


인덱스 파티션 (Index partition)
  • 파티션된 인덱스를 저장하는 세그먼트다.


LOB 파티션, LOB 서브파티션, LOB 인덱스, LOB 세그먼트 (Lob partition, lob subpartition, lobindex, and lob segment)
  • LOB 인덱스와 LOB 세그먼트는 대형 객체 또는 LOB 데이터를 저장한다.
  • 한 테이블을 파티션으로 구성한다면 LOB 세그먼트 또한 파티션으로 구성되며 LOB 파티션 세그먼트가 사용된다.
  • 어떤 이유 때문인지 LOB 인덱스 파티션 세그먼트 유형이 없다는 점은 흥미롭다.
    • 오라클은 파티션된 LOB 인덱스 세그먼트를 인덱스 파티션으로 기록한다
    • (그런데 왜 LOB 인텍스는 특별히 별도의 이름으로 부르는지는 모르겠다)


중첩 테이블 (Nested table)
  • 중첩 테이블을 저장하는 세그먼트유형이다.
  • 나중에 살펴볼 마스터/디테일 관계에서 자식 테이블의 특별한 경우에 시용된다.


롤백과 Type2 언두 (Rollback and Type2 undo)
  • 언두 데이터가 저장되는 세그먼트다.
  • 롤백 세그먼트는 DBA가 수동으로 생성해야 하지만,
  • Type2 언두 세그먼트는 오라클이 자동으로 생성하고 관리한다.


DEFFERED_SEGMENT_CREATION
  • 11G R1 까지는 테이블 생성하면 세그먼트 바로 생성
  • 11G R2 부터는 첫 번째 로우가 입력될 때까지 세그먼트 생성 보류. 디폴트 설정
  • 디폴트 설정을 바꾸려면 아래 문법을 사용하면 된다

ALTER SYSTEM DEFFERED_SEGMENT_CREATION=false;


  • 세그먼트 생성을 보류하지 않고 즉시 수행하려면 아래 문법을 사용하면 된다

CREATE TABLE t(x INT PRIMARY KEY, y CLOB, z BLOB) SEGMENT CREATION IMMEDIATE;


  • 세그먼트 생성이 보류된 테이블에 세그먼트를 할당하려면 아래 문법을 사용하면 된다

ALTER TABLE t ALLOCATE EXTENT;


Note(인덱스 재사용)
  • 유니크 또는 기본 키 제약은 새로운 인덱스를 생성하는 경우도 있고 생성하지 않는 경우도 있다.
  • 유니크 또는 기본 키 제약 컬럼이 기존의 특정 인덱스에 존재하고 해당 인덱스의 선두 컬럼에 위치한다면,
  • 새로운 인덱스를 생성하지 않고 기존 인덱스를 사용할 것이다.


  • Note 의 내용 확인을 위해 책과는 조금 다르게 테스트.
    • (x,w) 인덱스 생성 후 ( x ) PK 지정시 신규 인덱스 생성 없이 (x,w) 인덱스를 사용하는지 확인.



다음에 접속됨:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> CREATE TABLE t1(x INT, w INT, y CLOB, z BLOB);

테이블이 생성되었습니다.

SQL> CREATE INDEX x_t1 ON t1(x, w);

인덱스가 생성되었습니다.

SQL> ALTER TABLE t1 ADD PRIMARY KEY (x);

테이블이 변경되었습니다.

SQL> ALTER TABLE t1 ALLOCATE EXTENT;

테이블이 변경되었습니다.

SQL> SELECT segment_name, segment_type FROM user_segments;

SEGMENT_NAME                SEGMENT_TYPE
----------------------------------------
T1                          TABLE
SYS_IL0000076125C00003$$    LOBINDEX
SYS_IL0000076125C00004$$    LOBINDEX
X_T1                        INDEX
SYS_LOB0000076125C00003$$   LOBSEGMENT
SYS_LOB0000076125C00004$$   LOBSEGMENT

6 개의 행이 선택되었습니다.

SQL>


세그먼트 생성 확인
  • 하나의 테이블 생성 문장으로 6개의 세그먼트 생성
    1. TABLE
    2. INDEX
    3. CLOB 에 대한 LOBINDEX
    4. CLOB 에 대한 LOBSEGMENT
    5. BLOB 에 대한 LOBINDEX
    6. BLOB 에 대한 LOBSEGMENT


세그먼트 공간 관리

수동 세그먼트 공간 관리 (MSSM, Manual Segment Space Management)
  • 세그먼트를 할당하고, 사용하고, 재사용하기 위해 다양한 파라미터를 수동으로 지정한다.
  • MSSM 은 공식 용어는 아님.
  • 공간 할당을 지정하고, 고수준의 동시성 제어를 위해 수많은 파라미터 설정 튜닝 방안을 찾는 노력 필요


자동 세그먼트 공간 관리 (ASSM, Automatic Segment Space Management)
  • 공간을 사용하는 방법에 관한 PCTFREE 파라미터만을 조정할 수 있다.
  • 다른 파라미터는 세그먼트를 생성할 때 허용되기는 하지만 무시된다.
  • ASSM 세그먼트 방식을 위해서는 세그먼트가 ASSM 방식의 테이블스페이스에 존재해야 한다.


저장공간 및 세그먼트의 특성 에 영향을 주는 파라미터
  • BUFFER POOL
  • PCTFREE
  • INITRANS
  • MAXTRANS (9i에서만 사용됨, lOg 이상 무시)


HWM(하이-워터 마크)

  • 테이블의 데이터가 Delete 되어도 HWM 는 그대로 남는다.
  • 테이블 풀스캔시 HWM 까지 모두 읽는다. 비어 있는 블럭까지 모두 읽는 비효율 발생.
    • 테이블의 모든 자료를 지우려면? Delete 가 아닌 Truncate 이용.


HWM 를 낮추는 방법은?
  • 테이블 재생성, TRUNCATE, SHRINK
  • 세그먼트의 SHRlNK는 ASSM 테이블스페이스에서만 지원되며, 오라클 10g부터 지원.


하위 HWM 란?
  • ASSM 에서 도입된 개념으로 HWM 가 증가될 때 할당된 블럭을 즉시 포멧하지 않음
  • 하위 HWM 과 HWM 사이의 블럭은 실제 사용할 때 포멧된다.
  • 하위 HWM 과 HWM 사이의 블럭 사용여부 관리를 위해 ASSM 비트맵 정보를 사용한다.


FREELISTS

  • FREELIST는 MSSM 에서 의미있으며 객체의 HWM 아래의 블록 중 비어 있는 블록 정보를 관리한다.
  • FREELlSTS 와 FREELlST GROUPS 는 ASSM 에서는 전혀 사용되지 않는다. 오직 MSSM 에서만 사용되는 기법이다
  • 각 객체는 하나 이상의 FREELIST를 가지고 있으며,
  • 블록들이 시용되면서 펼요에 따라 FREELIST에 존재하거나 제거된다.
  • 객체의 HWM 아래의 블록만이 FREELIST로 사용된다
  • FREELIST 가 비었을 때 HWM을 증가시키고 블록을 FREESLIST에 추가한다.
  • 객체는 한 개 이상의 FREELIST를 가질 수 있다.
    • 충분한 FREELIST를 확보하는 것은 동시에 대량의 삽입과 삭제가 발생하는 환경에서 높은 성능 향상을 가져올 수 있다.
    • 그러나 FREELIST를 많이 지정하면 저장공간 비용이 추가로 발생한다.


  • 동시에 여러 세션에서 대량의 Insert 가 발생될 때
    • FREELIST가 부족한 테이블에서는 buffer busy waits 대기 이벤트 발생
  • 해결방안1. FREELISTS 크게 지정

CREATE TABLE t(x INT, y CHAR(50)) STORAGE (FREELISTS 5) TAB1ESPACE mssm;
ALTER TABLE t STORAGE (FREELISTS 5);


FREELISTS 를 크게 지정하기만 하면 문제가 없을까?
  • 마스터 FREELIST 와 프로세스 FREELIST 가 존재
  • 각 세션은 프로세스 FREELIST 에 배정된다
  • 프로세스 FREELIST 는 단지 몇개의 블록만을 가지며, 마스터 FREELIST 로 부터 블록 획득
  • 여러 프로세스에 여유가 있더라도 단 하나의 프로세스의 요청을 마스터가 처리하지 못하면 HWM 증가


FREELISTS 증감
  • SQL*Loader 의 Conventional path 사용시 FREELIST 를 증가시켜야 최적의 성능(최소 대기, 최고 동시성)
  • 로드 이후에는 적절한 수치로 감소해야 한다. 마스터 FREELIST 에 합병되어 공간 사용 증가를 막을 수 있다.


  • 해결방안2. ASSM 테이블스페이스 사용

CREATE TABLESPACE assm
DATAFILE 'c:\assm.dmp' SIZE 1M AUTOEXTEND ON NEXT 1M
SEGMENT SPACE MANAGEMENT AUTO;

  • 중요한 스토리지 파라미터의 설정을 수동으로 결정할 필요가 없다.


PCTFREE 와 PCTUSED

  • PCTFREE : 하나의 블록에 미래의 Update 를 위한 가용공간 비율. 기본값 10%
  • PCTUSED : 사용된 블록이 다시 가용공간이 되기 위한 사용공간 비율. 기본값 40%, ASSM(사용X)
  • PCTFREE 가 너무 높으면 공간낭비, 너무 낮으면 로우 이전 (Row Migration)


로우 이전 (Row Migration)
  • 로우 이전 (Row Migration) : 로우가 너무 커져 있던 블럭에 머무르지 못하고 다른 블록으로 이전하는 것
  • 로우 이전시 원래 위치에 이전된 주소를 남기고 이전, ROWID 는 그대로 유지



이전된 로우가 다시 이전해야 하는 상황이 발생된다면?
  • 최초 저장 블록에 공간이 충분하다면? 이곳으로 이전, 이전 안한것과 동일한 상태
  • 최초 저장 블록에 공간이 없다면? 다른곳으로 이전하고 초초 저장공간의 주소를 변경, 항상 1단계 유지.


PCTFREE 와 PCTUSED 설정하기
높은 PCTFREE 와 낮은 PCTUSED
  • 대량 갱신, 로우 크기 증가
  • Update 를 위한 가용공간 확보, 새로운 행 삽입 방지(Freelist 에 할당되지 않도록)


낮은 PCTFREE 와 높은 PCTUSED
  • 갱신이 없거나(삽입, 삭제만), 갱싱시 로우가 증가하지 않는 경우


LOGGING과 NOLOGGING

  • 테이블의 LOGGING 모드는 기본 모드로 테이블 작업시 리두를 생성
  • NOLOGGING 모드는 리두를 생성하지 않음
  • NOLOGGING 모드가 효과적일 때
    • 객체의 초기 생성
    • Direct Path 모드에서의 SQL*Loader 사용
    • 재구성(Rebuild)


INITRANS와 MAXTRANS

  • 각 세그먼트의 블록에는 블록 해더가 있다.
  • 블록 헤더의 한 부분으로 트랜잭션 테이블이 존재한다.
  • 이 트랜잭션 테이블에 만들어진 엔트리들은 어느 트랜잭션이 블록의 어떤 로우/요소에 락킹을 했는지를 보여준다.
  • 이 트랜잭션 테이블의 최소 크기는 객체의 INITRANS 설정 에 의해 명시된다.
  • 테이블의 기본값은 2고 인덱스의 기본값도 2다.
  • 이 트랜잭션 테이블은 블록에 충분한 빈 공간이 존재한다면 MAXTRANS까지 동적으로 증가할 것이다.
  • 각 할당된 트랜잭션 엔트리는 블록 헤더의 23~24바이트를 사용한다.
  • 오라클 10g 버전부터 MAXTRANS는 무시되며, 모든 세그먼트는 255 의 MAXTRANS를 가지고 있다.