세그먼트 (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개의 세그먼트 생성
- TABLE
- INDEX
- CLOB 에 대한 LOBINDEX
- CLOB 에 대한 LOBSEGMENT
- BLOB 에 대한 LOBINDEX
- 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 에 합병되어 공간 사용 증가를 막을 수 있다.
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를 가지고 있다.