블록, 익스텐트, 세그먼트
데이터 블록, 익스텐트, 세그먼트의 관계, 로컬 관리 테이블스페이스와 자동 세그먼트 공간 관리(ASSM), 익스텐트 할당 방식, 세그먼트가 넘을 수 있는 경계
#핵심 요약
데이터 블록이 모여 익스텐트가 되고, 익스텐트가 모여 세그먼트가 됨
세그먼트는 테이블이나 인덱스처럼 공간을 쓰는 객체임
익스텐트 하나는 데이터 파일 하나 안에만 있음
세그먼트는 같은 테이블스페이스 안에서 여러 데이터 파일에 걸칠 수 있지만, 테이블스페이스는 넘지 못함
로컬 관리 테이블스페이스(기본값)는 데이터 파일 헤더의 비트맵으로 익스텐트를 관리함
그 안에서 세그먼트 공간은 ASSM(기본값)이나 수동 방식으로 관리함
블록 크기는 테이블스페이스 속성임
한 세그먼트 안에서 블록 크기가 섞이지 않음
#개념과 동작 원리
#세 단위의 관계
| 단위 | 정의 |
|---|---|
| 데이터 블록 | 데이터 파일 안의 논리 저장 공간을 관리하는 최소 단위이자 I/O 최소 단위 Oracle 블록, 페이지라고도 함 |
| 익스텐트 | 논리적으로 연속된 데이터 블록의 묶음 항상 데이터 파일 하나 안에 있음 |
| 세그먼트 | 테이블스페이스 안에서 하나의 논리 저장 구조의 데이터를 모두 담는 익스텐트 집합 |
세그먼트의 익스텐트는 모두 같은 테이블스페이스에 있지만 서로 다른 데이터 파일에 있을 수 있음
파티션이 없는 객체와 각 파티션은 자기 세그먼트에 저장됨
인덱스 파티션이 다섯 개면 세그먼트도 다섯 개임
운영체제 블록과 데이터 블록은 크기가 다를 수 있음
데이터베이스는 데이터 블록 단위로 요청함
저장 구조의 경계는 다음과 같음
| 단위 | 데이터 파일을 넘는가 | 테이블스페이스를 넘는가 |
|---|---|---|
| 익스텐트 | 못 넘음 | 못 넘음 |
| 세그먼트 | 넘을 수 있음 | 못 넘음 |
| 테이블(논리 객체) | 넘음 | 파티션마다 다른 테이블스페이스를 지정하면 넘을 수 있음 |
#로컬 관리와 딕셔너리 관리
로컬 관리 테이블스페이스(기본값)는 데이터 파일 헤더의 비트맵으로 데이터 파일 본문의 여유 공간과 사용 공간을 추적함
딕셔너리 관리 테이블스페이스는 데이터 딕셔너리로 익스텐트를 관리함
익스텐트를 할당하거나 반환할 때마다 딕셔너리를 갱신하는 재귀 SQL이 직렬화되어 성능에 불리함
#세그먼트 공간 관리: ASSM과 수동
세그먼트 공간 관리 방식은 세그먼트가 속한 테이블스페이스에서 물려받음
같은 데이터베이스 안에서도 테이블스페이스마다 다르게 정할 수 있음
ASSM은 비트맵으로 공간을 관리함
영구 로컬 관리 테이블스페이스의 기본값이며 Oracle이 강하게 권장함
ASSM에서는 공간 할당을 좌우하는 주요 파라미터가 PCTFREE 하나임
프리 리스트를 쓰지 않고 PCTUSED를 무시함
수동 방식은 프리 리스트로 관리하며 세부 파라미터 조정이 어려움
설명: ASSM 세그먼트는 블록 공간 사용 현황을 나타내는 비트맵 블록(BMB)을 가짐
BMB는 최대 3단계 트리로 조직되고 최상위는 세그먼트 헤더에 있음
#익스텐트 할당
- 세그먼트를 만들면 기본적으로 첫 익스텐트가 할당됨
행이 없어도 그 익스텐트의 블록은 이 세그먼트 전용임 - 첫 익스텐트가 차면 증분 익스텐트를 자동으로 할당함
- 로컬 관리에서는 데이터 파일의 비트맵에서 인접한 여유 블록을 찾고, 부족하면 다른 데이터 파일을 찾음
- 사용자 세그먼트의 익스텐트는 대개
DROP하기 전에는 테이블스페이스로 돌아가지 않음
모든 행을 지워도 블록은 회수되지 않음
| 익스텐트 크기 방식 | 내용 |
|---|---|
| UNIFORM | 모든 익스텐트가 같은 크기 기본 1MB 로컬 관리 임시 테이블스페이스는 이 방식만 씀 |
| AUTOALLOCATE | 이후 익스텐트의 크기를 데이터베이스가 정함 |
#블록 크기
DB_BLOCK_SIZE는 데이터베이스를 만들 때 정해지고 SYSTEM, SYSAUX에 적용되며 다른 테이블스페이스의 기본값이 됨
데이터베이스를 다시 만들지 않으면 바꿀 수 없음
표준 블록 크기는 4KB 또는 8KB임DB_BLOCK_SIZE와 다른 블록 크기의 테이블스페이스를 따로 만들 수 있음
#필수 명령어 또는 SQL
#관리 방식이 다른 테이블스페이스 만들기
CREATE TABLESPACE space_test DATAFILE SIZE 20M
EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO;
CREATE TABLESPACE space_manual DATAFILE SIZE 20M
EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT MANUAL;SELECT tablespace_name, extent_management, segment_space_management
FROM dba_tablespaces
WHERE tablespace_name LIKE 'SPACE%';결과 해석:
예상값: 둘 다 EXTENT_MANAGEMENT가 LOCAL이고, SEGMENT_SPACE_MANAGEMENT는 SPACE_TEST가 AUTO, SPACE_MANUAL이 MANUAL임DATAFILE SIZE 20M처럼 경로 없이 쓰려면 DB_CREATE_FILE_DEST가 설정되어 있어야 하고, 없으면 경로를 직접 적으라고 수업 자료가 안내했음
#세그먼트가 두 데이터 파일에 걸치는지 확인
CREATE TABLESPACE span_ts
DATAFILE '<DATAFILE_DIR>/span01.dbf' SIZE 2M AUTOEXTEND OFF;
ALTER TABLESPACE span_ts
ADD DATAFILE '<DATAFILE_DIR>/span02.dbf' SIZE 5M AUTOEXTEND OFF;
CREATE TABLE <USERNAME>.span_demo (id NUMBER, txt VARCHAR2(1000))
SEGMENT CREATION IMMEDIATE
TABLESPACE span_ts;결과 해석:
첫 파일을 작게 잡고 자동 확장을 끈 것은 두 번째 파일로 넘어가게 하려는 것임SEGMENT CREATION IMMEDIATE는 행이 없어도 세그먼트를 바로 만듦
실습에서는 기본값인 지연 생성이면 익스텐트가 0개라고 적었음
INSERT INTO <USERNAME>.span_demo
SELECT LEVEL, RPAD('a', 900, 'a') FROM dual CONNECT BY LEVEL <= 500;
COMMIT;SELECT file_id, COUNT(*) AS extents,
MIN(extent_id) AS first_ext, MAX(extent_id) AS last_ext
FROM dba_extents
WHERE owner = '<USERNAME>' AND segment_name = 'SPAN_DEMO'
GROUP BY file_id
ORDER BY file_id;결과 해석:
예상값: 행을 넣기 전 익스텐트는 1개임
넣은 뒤에는 FILE_ID가 두 줄로 나오고, 첫 파일이 차면 다음 익스텐트부터 두 번째 파일에 할당됨
익스텐트 번호와 개수는 수업 자료도 환경마다 다르다고 적었음
#파티션마다 세그먼트가 따로 생기는지 확인
CREATE TABLE <USERNAME>.part_demo (id NUMBER, txt VARCHAR2(100))
PARTITION BY RANGE (id) (
PARTITION p1 VALUES LESS THAN (1000) TABLESPACE span_ts,
PARTITION p2 VALUES LESS THAN (2000) TABLESPACE users);
INSERT INTO <USERNAME>.part_demo SELECT LEVEL, 'x' FROM dual CONNECT BY LEVEL <= 1500;
COMMIT;SELECT segment_name, partition_name, tablespace_name, extents
FROM dba_segments
WHERE owner = '<USERNAME>' AND segment_name = 'PART_DEMO';결과 해석:
예상값: P1은 SPAN_TS, P2는 USERS로 두 줄이 나옴DBA_SEGMENTS는 한 행이 한 세그먼트임
테이블은 두 테이블스페이스에 걸치지만 세그먼트 하나가 두 테이블스페이스에 속하지는 않음
#블록 크기가 다른 테이블스페이스
ALTER SYSTEM SET db_16k_cache_size = 32M SCOPE = MEMORY;CREATE TABLESPACE ts16k
DATAFILE '<DATAFILE_DIR>/ts16k01.dbf' SIZE 10M
BLOCKSIZE 16384;결과 해석:
설명: 16K 버퍼 캐시를 먼저 잡지 않으면 ORA-29339가 남
실습 뒤 db_16k_cache_size를 0으로 되돌렸음
SELECT tablespace_name, bigfile, block_size
FROM dba_tablespaces
WHERE tablespace_name IN ('SPAN_TS', 'TS16K');결과 해석: 개별 실행 출력은 기재 없음
#스몰파일 데이터 파일의 상한
실습에서는 스몰파일 테이블스페이스에 33GB 파일을 붙이면 ORA-01144: File size (4325376 blocks) exceeds maximum of 4194303 blocks가 난다는 예상 결과를 적었음
공식 문서(Oracle Database Reference 19c E96196-45, Physical Database Limits)는 스몰파일 데이터 파일 하나가 약 4백만(2^22) 블록, 빅파일은 약 40억(2^32) 블록까지라고 적음
#정리
DROP TABLE <USERNAME>.part_demo PURGE;
DROP TABLESPACE ts16k INCLUDING CONTENTS AND DATAFILES;
DROP TABLESPACE space_manual INCLUDING CONTENTS AND DATAFILES;ALTER SYSTEM SET db_16k_cache_size = 0 SCOPE = MEMORY;결과 해석:
실습에서는 SPACE_TEST, SPAN_TS와 그 안의 테이블을 다음 실습(세그먼트 축소)에서 다시 쓰므로 지우지 않았음
#사용 조건과 주의사항
실습에서는 스몰파일 테이블스페이스의 데이터 파일이 최대 1,022개라고 적었음
공식 문서는 운영체제에 따라 다르며 보통 1023개라고 적음
실습 11.4절 실습은 SPAN_DEMO를 지운 뒤 블록 크기 비교에서 다시 SPAN_DEMO를 조회해 순서가 맞지 않음
위 블록 크기 확인은 테이블스페이스 조회로 바꿔 실었음
실습 11.4절 실습은 컨테이너 이름을 orclpdb로, 다른 단계는 orclppdb로 적었음
세그먼트 축소(SHRINK SPACE가 ASSM에서만 되는 실습), TRUNCATE ... REUSE STORAGE, 사용 불가 인덱스, 프라이빗 임시 테이블은 세그먼트 공간 회수 글 범위라 여기서 다루지 않음