Oracle DB에서 "shrink"는 테이블이나 테이블스페이스에서 사용되지 않는
여유 공간을 회수하여 데이터베이스의 전체 크기를 줄이는 작업을 의미한다.
데이터가 삭제되거나 트랜잭션이 완료된 후,
물리적으로 공간을 회수하지 않고 그대로 남아 있는 경우가 많다.
이 경우 "shrink"를 통해 실제로 사용 중인 공간 외에 남아 있는 빈 공간을 줄일 수 있다.
주로 다음과 같은 이유로 사용된다.
1. 디스크 공간 절약
삭제된 데이터의 공간이 남아 있으면 테이블스페이스 크기가 비대해질 수 있는데,
이때 shrink 작업을 통해 이를 최적화할 수 있다.
2. 성능 최적화
사용되지 않는 공간을 줄이면 디스크 I/O가 줄어들 수 있고, 이는 쿼리 성능 향상에 기여할 수 있다.
Oracle DB에서는 다음과 같은 명령어로 shrink 작업을 수행할 수 있다:
ALTER TABLE 테이블명 ENABLE ROW MOVEMENT;
ALTER TABLE 테이블명 SHRINK SPACE;
* 주의사항
- "shrink"는 데이터가 디스크에서 물리적으로 재배치될 수 있기 때문에,
일부 성능 저하가 발생할 수 있으며, 인덱스가 재구성될 수 있다.
트랜잭션이 많이 일어나는 테이블에 대해서는 신중하게 사용해야 한다.
- Online 환경에서 작업할 경우에도 락이 걸릴 수 있으므로 주의가 필요하다.
그럼 shrink를 사용해야 하는 이유는 무엇일까?
근본적으로 DB의 물리적 공간이 정리가 안되고 있었던 이유에 대해서 알아보자
Oracle DB에서 물리적 공간이 즉시 회수되지 않는 이유는 데이터베이스가 성능과 안정성을 우선시하기 때문이다.
주된 이유는 다음과 같다.
1. 성능 최적화
데이터가 삭제되거나 업데이트될 때마다 즉시 물리적 공간을 재구성하는 것은 상당한 오버헤드를 발생시킨다.
이를 피하기 위해, Oracle은 삭제된 데이터의 공간을 논리적으로 비어 있는 상태로 표시하고,
나중에 다른 데이터로 채워질 때까지 물리적으로 그대로 남겨 둔다.
즉, 공간 회수 작업을 즉각 수행하지 않음으로써 성능 저하를 방지하는 것이다.
2. 데이터 무결성 및 트랜잭션 관리
Oracle DB는 트랜잭션을 통해 데이터 무결성을 유지한다.
트랜잭션이 커밋되기 전까지는 데이터가 실제로 삭제되거나 변경되지 않으며,
이를 관리하기 위한 undo, redo 로그 등이 함께 관리된다.
이러한 과정에서 데이터를 삭제할 때마다 공간을 물리적으로 회수하게 되면,
트랜잭션 로그와 데이터 무결성 관리에 과도한 부담이 발생할 수 있다.
3. 공간 재사용을 위한 설계
Oracle은 공간을 즉시 회수하지 않고, 향후 다른 데이터가 삽입되면 해당 공간을 재사용할 수 있도록 설계되었다.
따라서 데이터 삭제 후에도 공간을 물리적으로 유지하고 있다가, 다시 데이터가 추가될 때 효율적으로 재사용할 수 있다.
이는 빈번한 데이터 삭제 및 삽입이 발생하는 테이블의 경우, 매번 공간을 재배치하는 것보다 훨씬 효율적이다.
4. 프래그멘테이션 방지
데이터를 물리적으로 삭제할 때마다 공간을 회수하면, 디스크에서 작은 조각들이 많이 발생할 수 있다(프래그멘테이션).
이로 인해 성능이 저하될 수 있기 때문에, 이러한 문제를 최소화하기 위해 Oracle은 공간을 즉각 회수하지 않고,
필요 시 한꺼번에 최적화할 수 있도록 설계되었다.
따라서, Oracle에서는 공간 회수가 자동으로 이루어지기보다는
수동으로 shrink 명령어 등을 통해 사용자가 직접 수행하도록 하여 성능과 효율성을 유지한다.
그럼 오라클 idb 파일과 truncate 명령어는 연관성이 있을까?
Oracle DB의 IDB 파일(일반적으로 데이터 파일을 의미)과 TRUNCATE 명령어는
둘 다 데이터와 저장 공간 관리와 관련이 있지만,
그 작동 방식과 연관성에는 중요한 차이가 있다.
두 개념의 관계를 구체적으로 살펴보면 다음과 같다.
1. IDB 파일 (데이터 파일)
- Oracle 데이터베이스에서 IDB 파일은 테이블스페이스의
물리적 저장 공간을 관리하는 데이터 파일이다.
이 파일은 실제로 데이터를 저장하며, 테이블에 저장된 모든 행과 데이터는 이 데이터 파일에 기록된다.
데이터 파일은 물리적 디스크에 존재하며, 데이터베이스의 크기,
저장된 데이터의 양에 따라 확장될 수 있다.
- 데이터가 삭제되거나 변경되더라도, 해당 공간이 자동으로 줄어들지 않는다.
빈 공간이 남을 수 있으며, 필요 시 shrink 등의 명령어를 통해 줄일 수 있다.
2. TRUNCATE 명령어
- TRUNCATE는 테이블에서 모든 데이터를 빠르게 삭제하는 명령어다.
DELETE 명령어와 다르게 TRUNCATE는 데이터만 제거할 뿐만 아니라,
삭제된 데이터에 대한 UNDO 정보도 남기지 않기 때문에 성능이 매우 빠르다.
트랜잭션을 롤백할 수 없고, 테이블의 모든 데이터가 영구적으로 삭제된다.
- TRUNCATE는 데이터를 삭제할 때 물리적 공간을 회수하지는 않지만,
논리적으로는 데이터 블록을 비우고 테이블의 고수준 메타데이터를 초기화한다.
따라서 테이블에 할당된 공간(세그먼트)은 남아 있을 수 있지만,
그 공간은 새로운 데이터를 위해 재사용될 수 있게 된다.
TRUNCATE와 IDB 파일의 연관성
- TRUNCATE 명령어를 실행해도 IDB 파일의 크기는 자동으로 줄어들지 않는다.
즉, 테이블에 있는 모든 데이터가 삭제되어도 그 테이블에 할당된 공간이 즉시 데이터 파일에서 해제되거나 줄어드는 것은 아니다.
데이터 파일은 여전히 동일한 크기를 유지하며, 그 빈 공간은 이후 다른 데이터 삽입을 위해 재사용될 수 있다.
예를 들어, 테이블이 데이터를 저장하는 데 1GB의 공간을 사용하고 있었고,
TRUNCATE로 데이터를 삭제하더라도, 이 1GB는 여전히 테이블스페이스에 할당된 상태다.
다만, TRUNCATE 이후 그 공간은 비어 있는 상태로, 새로운 데이터가 삽입될 때 사용된다.
물리적으로 데이터 파일의 크기를 줄이려면, shrink space 또는
테이블스페이스 재구성과 같은 별도의 명령을 수행해야 한다.
* 요약:
- TRUNCATE는 데이터를 빠르게 삭제하고 공간을 논리적으로 해제하지만,
물리적 공간(IDB 파일) 자체를 줄이지는 않는다.
- 데이터 파일의 크기를 줄이기 위해서는 TRUNCATE 이후에 별도로
shrink 명령이나 테이블스페이스 최적화 작업이 필요하다.
그럼 위에서 언급된 UNDO 라는 건 대체 뭘까 ?
Oracle DB에서 Undo 정보는 데이터 변경 작업(예: INSERT, UPDATE, DELETE) 중
발생한 이전 상태를 저장하는 데 사용되는 정보다.
이것은 데이터베이스에서 트랜잭션 관리와 데이터 무결성을 보장하는 중요한 개념이다.
Undo 정보를 사용하는 주요 목적은 트랜잭션을 롤백하거나, 읽기 일관성을 유지하는 것이다.
Undo 정보의 주요 기능
1. 트랜잭션 롤백 (Rollback)
- 트랜잭션이 완료되기 전에 오류가 발생하거나 사용자가 트랜잭션을 취소하는 경우,
Undo 정보는 해당 트랜잭션이 시작되기 전의 데이터 상태로 복구하는 데 사용된다.
이 과정은 "롤백"이라고 하며, 데이터 무결성을 보장하는 데 필수적이다.
- 예를 들어, 사용자가 10개의 행을 업데이트한 후 문제가 발생하여 롤백을 수행하면,
Oracle은 Undo 정보를 사용해 변경된 행들을 이전 상태로 복구한다.
2. 읽기 일관성 (Read Consistency)
- Oracle은 다중 사용자 환경에서 데이터 일관성을 유지하기 위해 읽기 일관성을 제공한다.
예를 들어, 한 사용자가 테이블에서 데이터를 변경하고 있을 때 다른 사용자가 해당 데이터를 조회하면,
변경 중인 데이터를 읽는 대신 변경 이전의 데이터를 읽을 수 있어야 한다.
이때 Undo 정보는 이전 데이터를 조회하는 데 사용된다.
- 즉, 사용자는 트랜잭션이 완료되지 않았을 때도 안전하게 읽을 수 있는 데이터 버전을 보장받는다.
3. 트랜잭션 재실행 방지
- 트랜잭션이 중간에 실패하거나 네트워크 오류로 인해 중단될 때 Undo 정보를 사용해 트랜잭션을 취소하거나
이전 상태로 돌림으로써 중복 실행이나 데이터 손상을 방지할 수 있다.
Undo의 저장 및 관리
Undo 정보는 데이터 변경 작업이 일어날 때마다 Undo 세그먼트라는 특별한 저장 영역에 기록된다.
Undo 세그먼트는 Oracle에서 자동으로 관리되며,
충분한 공간이 있어야 트랜잭션 관리가 원활하게 이루어진다.
또한 Oracle 10g 이상에서는 Automatic Undo Management (AUM) 기능을 제공해 Undo 공간을 자동으로 관리하고,
필요에 따라 크기를 확장할 수 있다.
TRUNCATE와 Undo 정보
- TRUNCATE 명령어는 테이블의 데이터를 모두 삭제하지만,
Undo 정보는 기록하지 않는다.
이는 TRUNCATE가 데이터만 삭제하는 것이 아니라 테이블의 메타데이터를 초기화하고,
관련된 모든 데이터를 즉시 제거하기 때문에 성능이 매우 빠르다.
반면에 DELETE 명령어는 각 행의 삭제 작업에 대해 Undo 정보를 생성하기 때문에
성능이 TRUNCATE에 비해 느릴 수 있다.
* 요약:
Undo 정보는 트랜잭션 롤백, 읽기 일관성 보장, 트랜잭션 관리 등의 중요한 역할을 하며,
Oracle DB의 신뢰성과 무결성을 유지하는 데 필수적이다.
마지막으로 TRUNCATE와 DROP TABLE 명령의 차이점을 알아보자
DROP TABLE 과 TRUNCATE는 둘 다 Oracle에서 테이블의 데이터를 삭제하는데 사용되지만,
그들의 동작 방식과 영향은 크게 다르다. 각 명령어의 차이점은 다음과 같다.
1. DROP TABLE
DROP TABLE은 테이블과 관련된 모든 데이터, 인덱스, 트리거, 제약 조건 등 모든 객체를 삭제한다.
단순히 데이터를 삭제하는 것이 아니라, 테이블 자체와 관련된 모든 정보가 데이터베이스에서 사라지기 때문에
매우 파괴적인 명령어다.
- 작동 방식
- 테이블에 저장된 데이터뿐만 아니라 테이블 자체도 삭제된다.
- 테이블을 삭제하면 이 테이블과 관련된 인덱스, 제약 조건(constraints), 트리거,
참조 무결성 정보 등도 모두 함께 삭제된다.
- UNDO 정보는 생성되지 않는다. 따라서 롤백이 불가능하다.
- 테이블을 다시 복구하려면, 데이터를 다시 생성하거나 백업에서 복구해야 한다.
- 사용 예시
DROP TABLE 테이블명;
- 영향
- 테이블에 할당된 공간은 자동으로 해제되며,
해당 공간은 테이블스페이스에서 다른 객체가 사용할 수 있게 된다.
- 삭제된 테이블은 더 이상 존재하지 않으므로 SELECT 같은 쿼리를 실행할 수 없다.
- 삭제된 테이블은 RECYCLE BIN에 저장되어 복구 가능할 수 있다(Oracle Recycle Bin 사용 시).
2. TRUNCATE
TRUNCATE는 테이블의 모든 데이터를 삭제하지만, 테이블 구조와 관련된 객체(인덱스, 제약 조건 등)는 유지된다.
TRUNCATE는 성능이 매우 빠르며, 대량의 데이터를 삭제할 때 많이 사용된다.
- 작동 방식
- 테이블의 모든 데이터만 삭제되며, 테이블 구조, 인덱스, 제약 조건 등은 유지된다.
- TRUNCATE는 내부적으로 데이터 블록을 재설정하므로 DELETE보다 훨씬 빠르다.
- UNDO 정보는 생성되지 않기 때문에 롤백이 불가능하다.
- 테이블에 저장된 데이터만 지우고, 테이블 자체는 그대로 남아 있어 테이블을 계속 사용할 수 있다.
- 사용 예시
TRUNCATE TABLE 테이블명;
- 영향
- 테이블에 할당된 공간은 비워지지만, 테이블 구조는 남아 있으며,
해당 공간은 새로운 데이터 삽입을 위해 재사용될 수 있다.
- 인덱스는 초기화되지만 삭제되지 않는다.
- 참조 무결성 제약 조건(외래키 제약)과 연관된 테이블은 TRUNCATE할 수 없다.
주요 차이점 요약
요약
- DROP TABLE
테이블과 그 안에 있는 모든 데이터와 객체를 영구적으로 삭제한다.
테이블 자체가 삭제되며, 복구가 어렵다. 삭제된 공간은 즉시 회수된다.
- TRUNCATE
테이블의 데이터만 삭제하고, 테이블 구조와 인덱스 등은 유지된다.
성능이 빠르며 대량의 데이터를 빠르게 삭제할 때 유용하지만, 롤백은 불가능하다.
* 이외 생각해볼만한 사항들
Q1: DROP TABLE을 사용했을 때 삭제된 테이블을 복구할 수 있는 방법은 무엇일까?
Q2: TRUNCATE 명령어가 참조 무결성 제약을 가진 테이블에 사용될 수 없는 이유는 무엇일까?
Q3: 대량의 데이터를 삭제할 때 TRUNCATE보다 DELETE 명령어를 사용해야 하는 경우는 언제일까?
'무근본 IT 지식 공유' 카테고리의 다른 글
[무근본JAVASCRIPT] javascript에서 serialize가 필요한 이유 (3) | 2024.11.27 |
---|---|
[무근본DB지식] 오라클 쿼리로 간단하게 테이블 컬럼 정보 조회하는 방법 ! (0) | 2024.10.05 |
인터넷 브라우저 설정을 통해 로컬 폰트를 막는 법 (0) | 2024.07.09 |
chrome에서 로컬 폰트 사용하는 것을 막는 방법 (0) | 2024.07.09 |
pdfjs 오픈 소스에서 blob 방식을 안쓰고 base64 방식을 쓰는방법 (0) | 2024.07.09 |
댓글