VACUUM에는 Analyze, Freeze, Verbose 처럼 Truncate 라는 옵션이 있습니다.
Trunacte는 일반적으로 데이터를 삭제하는 작업처럼 느껴지는데요 Vacuum에서는 어떤 역할을 하는지 정리하고자 합니다.
Vacuum Truncate는 일반적으로 Default 옵션으로 별도 지정이 없을 경우 동작합니다(Auto Vacuum도 동일합니다).
이 동작은 Table의 끝에 있는 페이지가 비어있을 경우 해당 공간을 O.S에 반환하는 동작을 합니다.
TRUNCATE
Specifies that VACUUM should attempt to truncate off any empty pages at the end of the table and allow the disk space for the truncated pages to be returned to the operating system.
This is normally the desired behavior and is the default unless the vacuum_truncate option has been set to false for the table to be vacuumed.
Setting this option to false may be useful to avoid ACCESS EXCLUSIVE lock on the table that the truncation requires. This option is ignored if the FULL option is used.
--https://www.postgresql.org/docs/16/sql-vacuum.html
중요한 점은 해당 작업에서 프로세스는 테이블에 대하여 Access Exclusive Lock을 요청하게 된다는 점입니다.
일반적으로 수행되는 VACUUM은 DML의 작업에 영향이 없는 수준으로 동작하는 것으로 이해하고 있을 때 해당 동작은 예상치 못한 서비스 장애를 야기시킬 수 있습니다.
또한 해당 동작은 Heap 구조인 테이블에서만 동작하고 B-Tree 구조인 인덱스에서는 동작하지 않습니다.
만약 대량의 데이터가 delete 되어 테이블의 경우 데이터가 대부분 사라질 경우 Truncate 동작에 의하여 테이블의 사이즈는 감소되어도 인덱스의 사이즈는 O.S에 반환되지 않고 Bloat 한 상태로 남아 있을 수 있습니다.
(인덱스의 Tuple 생명주기는 테이블의 Tuple 처럼 Use -> deleted -> reusable 로 되는데 위 상황이라면 인덱스는 reusable 상태로 오래 남아 Bloat 현상을 야기합니다)
만약 대량의 데이터를 일괄 삭제하는 작업 등이 필요한 서비스라면 아래와 같은 튜닝으로 서비스 이슈를 예방할 수 있습니다.
1. TABLE의 VACUUM_TRUNCATE 옵션 OFF 설정 (18버전 이상이라면 파라미터로 관리 가능)
2. 서비스 영향이 적은 시점에 수동 VACUUM TRUNCATE 명령어 수행
참조
https://blog.summercat.com/postgres-vacuum-taking-an-access-exclusive-lock.html
https://runebook.dev/en/docs/postgresql/runtime-config-vacuum/GUC-VACUUM-TRUNCATE
'공부 > DATABASE' 카테고리의 다른 글
| [Aurora MySQL] OOM과 Performance Schema (0) | 2026.04.05 |
|---|---|
| [AWS DocumentDB] 간헐적 입력 지연 이슈 (0) | 2026.03.07 |
| Jenkins 로 Terraform 호출하여 AWS RDS 생성하기 (0) | 2026.02.14 |
| [PostgreSQL, MySQL] DBMS에서 인데스 조회 중 I/O 줄이는 방식 (0) | 2026.02.01 |
| [Aurora PostgreSQL] 테이블 DROP (0) | 2026.02.01 |