| 79번째 줄: | 79번째 줄: | ||
# LOB 세그먼트는 내부적으로 CHUNK(기본 8KB, 블록 사이즈 배수) 단위로 분할 저장. | # LOB 세그먼트는 내부적으로 CHUNK(기본 8KB, 블록 사이즈 배수) 단위로 분할 저장. | ||
# 큰 데이터를 CHUNK들의 연결 리스트로 관리하기 때문에 부분 읽기/쓰기(random access)가 가능하고, 전체를 메모리에 올리지 않고도 스트리밍 처리가 가능. | # 큰 데이터를 CHUNK들의 연결 리스트로 관리하기 때문에 부분 읽기/쓰기(random access)가 가능하고, 전체를 메모리에 올리지 않고도 스트리밍 처리가 가능. | ||
* CHUNK란? | |||
** LOB 데이터의 최소 I/O 단위 | |||
** DB_BLOCK_SIZE의 배수여야 함 (기본값: DB_BLOCK_SIZE, 최대 32KB 권장) | |||
** 하나의 CHUNK는 여러 Oracle Block으로 구성 가능하나, 하나의 익스텐트 내에 존재 | |||
=== LOB 인덱스 === | === LOB 인덱스 === | ||
2026년 9월 7일 (월) 14:27 판
LOB(BLOB/CLOB)대용량 데이터
개요
LOB(BLOB/CLOB)이 대용량 데이터를 저장하는 핵심 원리는 "포인터(로케이터) + 별도 세그먼트 분리 저장" 구조
LOB
├── Internal LOB (DB 내부 저장)
│ ├── CLOB (Character LOB) - 문자 데이터
│ ├── NCLOB (National CLOB) - 다국어 문자셋
│ └── BLOB (Binary LOB) - 바이너리 데이터
└── External LOB
└── BFILE - OS 파일시스템 참조 (읽기 전용)
CLOB vs VARCHAR2 근본적 차이
- VARCHAR2: 최대 32767 bytes (PL/SQL , 19c 이상부터 SQL도 가능), 4000 bytes (SQL) - inline storage 강제
- CLOB: 최대 4GB * DB_BLOCK_SIZE (이론상 128TB) - out-of-line storage 가능
LOB 저장 구조 (핵심)
Table Row
│
▼
┌─────────────┐
│ LOB LOCATOR │ ← 테이블 로우에 실제 저장되는 것 (포인터/핸들)
│ (약 4KB↓) │
└─────────────┘
│
▼
┌─────────────┐
│ LOB INDEX │ ← LOB 청크들을 관리하는 B-Tree 인덱스
└─────────────┘
│
▼
┌─────────────┐
│ LOB SEGMENT │ ← 실제 데이터가 저장되는 세그먼트 (CHUNK 단위)
└─────────────┘
LOB 로케이터(LOCATOR)
- 테이블 로우에는 실제 데이터가 아니라 LOB 데이터를 가리키는 40바이트 내외의 로케이터(포인터)만 저장됨
- 실제 데이터는 별도의 LOB 세그먼트에 존재하고, 애플리케이션은 이 로케이터를 통해 스트리밍 방식(READ/WRITE by chunk)으로 데이터에 접근함
In-row vs Out-of-row
- - 데이터 크기가 작으면(기본 임계값 관련, ENABLE STORAGE IN ROW) 로우 내부에 직접 저장
- - 임계값을 넘으면 별도의 LOB 세그먼트(out-of-row)에 체인 형태로 저장되고 로우에는 포인터만 남음
- - 이 덕분에 4000바이트 제한을 가진 VARCHAR2/RAW와 달리 최대 4GB(BasicFile) ~ (LOB) 단위까지 저장 가능
CLOB 데이터 크기 확인
│
├── 4000 bytes 이하 (기본값)
│ └── ENABLE STORAGE IN ROW
│ → 로우 내부에 직접 저장 (Inline)
│ → LOB Locator + 실제 데이터가 로우에 존재
│
└── 4000 bytes 초과 (또는 DISABLE STORAGE IN ROW)
└── OUT OF ROW 강제 이동
→ 로우에는 LOB Locator만 존재
→ 실제 데이터는 별도 LOB Segment에 저장
- 저장 방식 확인 테스트
CREATE TABLE lob_test (
id NUMBER,
doc CLOB
) LOB (doc) STORE AS (
ENABLE STORAGE IN ROW -- 4000바이트 이하는 인라인
CHUNK 8192 -- 청크 크기
PCTVERSION 10 -- 버전 유지 비율
NOCACHE -- 버퍼캐시 사용 안함
LOGGING
);
- 성능 함정: 4000바이트 근처의 데이터가 빈번하게 업데이트되면 in-row ↔ out-of-row 전환이 발생하여 Row Migration과 유사한 오버헤드 발생.
CHUNK 단위 저장
- LOB 세그먼트는 내부적으로 CHUNK(기본 8KB, 블록 사이즈 배수) 단위로 분할 저장.
- 큰 데이터를 CHUNK들의 연결 리스트로 관리하기 때문에 부분 읽기/쓰기(random access)가 가능하고, 전체를 메모리에 올리지 않고도 스트리밍 처리가 가능.
- CHUNK란?
- LOB 데이터의 최소 I/O 단위
- DB_BLOCK_SIZE의 배수여야 함 (기본값: DB_BLOCK_SIZE, 최대 32KB 권장)
- 하나의 CHUNK는 여러 Oracle Block으로 구성 가능하나, 하나의 익스텐트 내에 존재
LOB 인덱스
LOB 세그먼트의 CHUNK 위치를 추적하기 위해 별도의 LOB 인덱스가 존재합니다(B-tree 구조로 CHUNK 매핑 관리).
LOB 세그먼트 정보 확인
SELECT table_name, column_name, segment_name, index_name,
chunk, pctversion, cache, logging, in_row
FROM user_lobs -- dba_lobs
WHERE table_name = 'YOUR_TABLE';
SecureFile vs BasicFile
- - BasicFile: 전통적 방식, LOB 세그먼트에 체인 저장
- - SecureFile(11g+): ASSM 기반, 압축/중복제거/암호화 지원, 성능 개선된 구조로 대부분 권장
즉, "행 안에 다 넣지 않고 별도 세그먼트에 청크 단위로 분산 저장 + 로케이터로 참조"하는 것이 대용량 저장의 핵심 메커니즘입니다.
- Oracle 19c LOB 저장 속성 정리
- LOB STORAGE 절 기본 구조
LOB (column_name) STORE AS [SECUREFILE|BASICFILE] [lob_segment_name] ( TABLESPACE ... ENABLE|DISABLE STORAGE IN ROW CHUNK n PCTVERSION n | RETENTION [AUTO|MAX n|MIN n] FREEPOOLS n CACHE | NOCACHE | CACHE READS LOGGING | NOLOGGING COMPRESS [LOW|MEDIUM|HIGH] DEDUPLICATE | KEEP_DUPLICATES ENCRYPT ... | DECRYPT )
- 속성별 정리
| 속성 | 설명 | 비고 |
|---|---|---|
| **SECUREFILE / BASICFILE** | LOB 저장 방식 선택 | SecureFile 권장(기본값은 DB_SECUREFILE 파라미터에 따름) |
| **ENABLE/DISABLE STORAGE IN ROW** | 로우 내 인라인 저장 여부 | 임계값 이하 데이터는 IN ROW 저장 |
| **CHUNK** | LOB 저장 최소 단위(바이트) | 블록사이즈 배수, 기본 8K |
| **PCTVERSION** | (BasicFile 전용) 이전 버전 유지 공간 % | Undo 방식과 다른 read consistency |
| **RETENTION [AUTO/MAX/MIN]** | (SecureFile 전용) 버전 보존 정책 | AUTO가 일반적 |
| **CACHE / NOCACHE / CACHE READS** | 버퍼캐시 사용 여부 | 대용량은 보통 NOCACHE |
| **LOGGING / NOLOGGING** | Redo 생성 여부 | 대량 초기 적재시 NOLOGGING 고려 |
| **COMPRESS [LOW/MEDIUM/HIGH]** | (SecureFile 전용) 압축 레벨 | ACO(Advanced Compression) 라이선스 필요 |
| **DEDUPLICATE / KEEP_DUPLICATES** | (SecureFile 전용) 중복 제거 | ACO 라이선스 필요 |
| **ENCRYPT / DECRYPT** | TDE 필요 | |
| **FREEPOOLS** | (SecureFile 전용) 동시성 향상용 free space pool 분리 | RAC 환경 동시 write 성능 |
- 🆕 19c 관련 New Feature / 변경사항
- 1. `DB_SECUREFILE` 파라미터 기본값 변경 없음, 단 SecureFile이 사실상 표준화**
- 12c부터 BasicFile은 "desupported"(deprecated) 상태 유지, 19c에서도 동일하게 BasicFile은 신규 개발에 비권장
- 2. LOB 관련 초기화 파라미터 정리 지속**
- `DB_SECUREFILE` 파라미터 값: `PERMITTED`(기본), `ALWAYS`, `FORCE`, `NEVER`, `IGNORE` - 19c에서도 동일 옵션 유지, ALWAYS/FORCE 사용시 BasicFile 문법도 자동으로 SecureFile로 생성
- 3. JSON 관련 LOB 활용 강화 (19c 특징)**
- 19c의 확장된 JSON 지원(다중 JSON 컬럼, 부분 업데이트 등)이 내부적으로 SecureFile LOB 기반으로 동작 — LOB 자체의 새 절이라기보다는 LOB을 활용하는 상위 기능 확장
- 4. In-Memory 관련**
- 19c에서 `INMEMORY` 절은 LOB 자체에는 직접 적용 불가(LOB은 IM 컬럼 스토어 미지원) — 이 제약은 계속 유지됨(신규 아님, 혼동 주의사항으로 정리)
- 참고**: 19c 자체에서 LOB STORE AS 문법 자체에 **완전히 새로운 키워드가 추가된 것은 없고**, 12c~18c에서 도입된 SecureFile 관련 옵션들이 19c에서도 그대로 유지·강화되는 흐름입니다. 12c 이후 큰 변화는 없었고, 오히려 "BasicFile 지양, SecureFile 표준화"라는 정책적 방향이 19c에서 더 굳어진 것으로 보시면 됩니다.
특정 옵션(예: COMPRESS, DEDUPLICATE의 라이선스 조건이나 RAC FREEPOOLS 튜닝)에 대해 더 깊게 필요하시면 말씀해주세요.