테이블스페이스(Tablespace): 논리적 단위


"데이터 파일은 혼자 존재하지 않습니다. 반드시 테이블스페이스라는 논리적인 바구니에 담겨야 합니다."
- 1:N 관계: 하나의 테이블스페이스는 여러 개의 데이터 파일을 가질 수 있습니다.
- 관리의 편의성: 유저에게 "데이터 파일 A에 저장해"라고 하지 않고, "TS_DATA 테이블스페이스에 저장해"라고 지정하면 오라클이 알아서 소속된 데이터 파일에 나눠 담습니다.
- 기본 종류
- SYSTEM / SYSAUX: 오라클 시스템 운영을 위한 필수 정보
- UNDO: 과거 데이터를 보관(RollBack용)
- TEMP: 정렬 작업 등을 위한 임시 공간
- USERS: 일반 사용자의 실제 데이터
데이터 파일의 내부 구조


"오라클은 파일을 통째로 다루지 않고, 아주 작은 단위로 쪼개서 관리합니다."
- 논리적 포함 관계: 테이블스페이스 > 세그먼트 > 익스텐트 > 데이터 블록
- 데이터 블록 (Data Block): 오라클의 최소 입출력 단위입니다. (보통 8KB) 우리가 한 줄의 데이터를 넣으면 이 블록 안에 저장됩니다.
- 익스텐트 (Extent): 연속된 블록들의 모음입니다. 공간이 더 필요하면 오라클은 블록 하나씩이 아니라 '익스텐트' 단위로 공간을 할당합니다.
- 세그먼트 (Segment): 특정 논리 구조(테이블, 인덱스 등)에 할당된 모든 익스텐트의 합입니다. 즉, "Table A = Segment A"라고 이해하면 쉽습니다.
- 세그먼트의 종류
- Data 세그먼트: 클러스터화 되지 않은 각각의 비인덱스 구성 테이블에는 데이터 세그먼트가 있다.
- Index 세그먼트: 각 인덱스는 해당 데이터를 모두 저장하는 데이터 세그먼트를 가짐.
- Undo 세그먼트: 각 instance당 하나의 undo 테이블스페이스 생성.
- Temp 세그먼트: SQL문에서 실행을 완료할 임시 작업 영역이 필요할 때 생성.
- 세그먼트의 종류
💡 시나리오로 감 잡기 (실무 응용 편)
이번 글은 실무에서 중요한 포인트이기 때문에 시나리오가 많아도 한번씩 읽어보는 것을 추천드립니다!
시나리오 1. "데이터를 지웠는데 왜 여전히 공간 부족 에러가 날까?"
- 상황: 테이블스페이스가 99% 차서 급하게 데이터를 DELETE로 대량 삭제했습니다. 그런데 여전히 새로운 데이터를 넣으려고 하면 "공간 부족" 에러가 발생합니다.
👇원인과 해결
더보기
- 원인: DELETE는 블록 안의 '내용물'만 지우는 것이지, 할당된 '땅(Extent)' 자체를 반납하는 게 아니기 때문입니다. 이 땅은 여전히 해당 테이블이 소유하고 있어 다른 테이블이 가져다 쓸 수 없습니다.
- 해결: 해당 테이블에 데이터를 다시 넣는다면 상관없지만, 다른 테이블을 위해 공간을 확보해야 한다면 TRUNCATE를 하거나 테이블을 MOVE하여 빈 익스텐트를 테이블스페이스의 공용 공간(Free Space)으로 돌려보내야 합니다.
시나리오 2. "파일을 여러 개로 쪼개면 조회 속도가 빨라지는 이유"
- 상황: 100GB 데이터 파일 1개를 가진 테이블스페이스와, 10GB 파일 10개를 가진 테이블스페이스가 있습니다. 대량 조회를 하면 후자가 훨씬 빠릅니다.
👇원인과 해결
더보기
- 원인: 오라클은 데이터를 저장할 때 여러 파일에 골고루 분산(Round-Robin)해서 담습니다.
- 해결: 데이터가 10개 파일에 나뉘어 있으면, 데이터를 읽을 때 10개의 디스크 통로(I/O Path)를 동시에 사용할 수 있습니다. 이를 통해 병목 현상을 줄이고 활용도를 극대화할 수 있습니다.
시나리오 3. "특정 세션이 테이블 전체를 '인질'로 잡고 있어요"
- 상황: 한 사용자가 아주 큰 데이터를 넣다가 테이블스페이스가 꽉 찼습니다. 에러가 났는데 이 사용자가 로그아웃을 안 하고 자리를 비웠더니, 다른 사용자들도 해당 테이블에 접근을 못 하고 대기 중입니다.
👇원인과 해결
더보기
- 원인: 트랜잭션이 종료(Commit/Rollback)되지 않았기 때문입니다. 공간 부족 에러가 발생해도 해당 세션이 잡고 있던 Row Lock은 그대로 유지됩니다. 뒤따라온 사용자들이 같은 데이터를 수정하려다 앞사람의 '공간 부족 해결'을 기다리며 줄을 서게 되는 것입니다.
- 해결: 해당 세션을 찾아 강제로 종료(Kill Session)하여 롤백을 유도하거나, 즉시 테이블스페이스 용량을 늘려주어 멈춰있던 작업이 마무리되도록 해야 합니다.
시나리오 4. "데이터를 지웠는데 왜 '풀 스캔' 속도는 그대로일까?"
- 상황: 1억 건의 데이터를 지우고 10건만 남겼습니다. 당연히 조회가 빨라질 줄 알았는데, SELECT *를 하니 예전처럼 느리고 디스크 I/O가 폭주합니다.
👇해결과 원인
더보기
- 원인: HWM(High Water Mark) 때문입니다. 오라클은 테이블 전체 조회 시 데이터 존재 여부와 상관없이 '한때 데이터가 찼던 최고 높이(HWM)'까지 모든 블록을 다 읽습니다. 텅 빈 방 100만 개를 일일이 열어보며 10명을 찾는 꼴입니다.
- 해결: MOVE 명령으로 테이블을 재구성하여 HWM을 실제 데이터 높이로 낮춰줘야 합니다.
시나리오 5. "자동 확장(Autoextend)을 켰는데 왜 디스크가 꽉 찼죠?"
- 상황: 데이터 파일에 AUTOEXTEND ON MAXSIZE UNLIMITED 설정을 해두었습니다. "공간 모자랄 일은 없겠지"라고 안심했는데, 어느 날 새벽 서버의 모든 서비스가 멈추고 OS 로그인이 안 된다는 연락을 받았습니다.
👇원인과 해결
더보기
- 원인: 오라클 입장에서 '무제한'은 물리적인 디스크(OS 하드디스크)의 끝까지 쓰겠다는 뜻입니다. 데이터 파일이 혼자 디스크를 다 써버리는 바람에, OS가 숨 쉴 공간(Log, Temp 등)마저 사라져 서버 전체가 멈춘 것입니다.
- 해결: MAXSIZE를 디스크 전체 용량보다 적게(예: 80% 수준) 명시적으로 제한해야 합니다. "무제한"은 오라클의 한계가 아니라 디스크의 한계를 의미한다는 점을 잊지 마세요.
시나리오 6. "UNDO 테이블스페이스가 꽉 차면 조회가 안 되나요?"
- 제목: "수정(DML)도 아닌데, 왜 단순 조회가 UNDO 공간 부족으로 에러가 날까?"
- 상황: 대량의 데이터를 누군가 업데이트하고 있는 와중에, 다른 사용자가 그 데이터를 조회하려고 하니 ORA-30036: unable to extend segment in undo tablespace 에러가 발생하며 조회가 실패합니다.
👇원인과 해결
더보기
- 원인: 오라클의 '읽기 일관성(Read Consistency)' 때문입니다. 누군가 수정 중인 데이터를 조회할 때, 오라클은 수정 전의 원래 데이터를 UNDO에서 찾아 보여줘야 합니다. 그런데 UNDO 공간이 부족해서 과거 데이터를 덮어쓰게 되면 실패하게 됩니다.
- 해결: UNDO 테이블스페이스의 용량을 충분히 확보하거나, 한 번에 너무 많은 데이터를 수정하는 트랜잭션을 쪼개서 수행해야 합니다. 또는 Undo retention 파라미터를 설정하여 유지 시간을 길게 가져가야 합니다.
시나리오 7. "분명히 삭제했는데, 용량이 줄어들지 않는 공간'"
- 상황: 테이블스페이스의 전체 빈 공간 합계는 5GB입니다. 그런데 1GB짜리 새로운 익스텐트를 만들려고 하니 공간이 부족하다는 에러가 뜹니다.
👇원인과 해결
더보기
- 원인: 단편화(Fragmentation) 현상 때문입니다. 빈 공간들이 여기저기 0.1GB씩 흩어져 있다면, 오라클이 요구하는 연속된(Contigous) 1GB 공간을 만들 수 없습니다. 낱개 과자는 많지만 박스에 담을 자리가 없는 것과 같습니다.
- 해결: 흩어진 빈 공간들을 합쳐주는 작업(Coalesce)을 하거나, 테이블을 다른 테이블스페이스로 옮겼다 다시 가져오는 방식으로 조각모음을 수행해야 합니다.
시나리오 8. "파일 크기는 작은데, 백업 시간이 너무 오래 걸려요"
- 상황: 테이블스페이스 용량을 넉넉하게 쓰려고 100GB짜리 데이터 파일을 만들었습니다. 실제 데이터는 1GB뿐인데, 매일 밤 수행하는 전체 백업(Full Backup) 시간이 너무 오래 걸려 아침 업무 시간까지 영향을 줍니다.
👇원인과 해결
더보기
- 원인: 사용자 레벨의 카피 백업(OS Copy)을 사용하고 있기 때문입니다. OS 입장에서는 데이터 파일이 0.1%만 차 있어도 100GB짜리 거대한 덩어리일 뿐입니다.
- 해결: 오라클 전용 백업 도구인 RMAN(Recovery Manager)을 도입해야 합니다. RMAN은 데이터 파일 내의 '데이터가 들어있는 블록'만 골라서 백업하는 Unused Block Compression 기능이 있어 백업 시간과 용량을 획기적으로 줄여줍니다.
시나리오 9. "분명히 삭제(Drop)했는데, OS 용량이 안 늘어나요"
- 상황: 디스크 공간을 확보하기 위해 안 쓰는 테이블스페이스를 DROP TABLESPACE TS_OLD; 명령어로 삭제했습니다. 오라클 내부에서는 사라진 게 확인되는데, 정작 리눅스에서 df -h를 쳐보니 가용 용량이 그대로입니다.
👇원인과 결과
더보기
- 원인: 기본 DROP TABLESPACE 명령어는 오라클의 논리적 장부에서만 이름을 지울 뿐, 물리적인 데이터 파일(.dbf)은 삭제하지 않기 때문입니다. 만약의 실수에 대비해 오라클이 파일을 남겨두기 때문입니다.
- 해결: DROP TABLESPACE TS_OLD INCLUDING CONTENTS AND DATAFILES; 옵션을 사용해야 논리적 구조와 물리적 파일을 동시에 삭제하여 디스크 공간을 회수할 수 있습니다.
시나리오 10. "데이터 파일을 옮기고 싶은데 DB를 꺼야 하나요?"
- 상황: 특정 데이터 파일이 있는 디스크의 수명이 다해가서 새로운 디스크로 파일을 옮겨야 합니다. 하지만 24시간 서비스 중이라 DB를 끌 수 없는 상황입니다.
👇원인과 결과
더보기
- 원인: 과거 버전(12c 이전)에서는 테이블스페이스를 오프라인으로 만들어야 했지만, 최신 버전은 이를 허용합니다.
- 해결: ALTER DATABASE MOVE DATAFILE 명령어를 사용하면 DB가 가동 중인 상태(Online)에서도 물리적인 위치를 옮길 수 있습니다. 오라클이 내부적으로 파일 복사와 포인터 변경을 알아서 처리해주기 때문입니다.
'🗄️ DB_이야기 > # 🛢️ Oracle' 카테고리의 다른 글
| [Oracle] 출력 결과가 '#(샵)'으로 나오는 경우 (0) | 2026.03.24 |
|---|---|
| [Oracle] Oracle Archtecture(7) [Lock] (0) | 2026.03.21 |
| [Oracle] Oracle Architecture (5) [물리적 저장 구조] (1) | 2026.03.19 |
| [Oracle] Oracle Architecture(4) [백그라운드 프로세스] (1) | 2026.03.18 |
| [Oracle] Oracle Architecture(3) [SQL 처리 과정] (0) | 2026.03.17 |
