📢 Manual Vacuum에 이어, 본 문서 역시 ①Autovacuum이 무엇인지 알아보고, ②Autovacuum의 동작 조건 및 ③Autovacuum 프로세스에 의해 수행되는 Anti-Wraparound Vacuum에 대해 알아보도록 하겠습니다. 마지막으로 ④Autovacuum 전체 프로세스에 대해 확인해보도록 하겠습니다.
Autovacuum
Autovacuum이란 Vacuum수행을 자동화해주는 기능을 이야기합니다. Autovacuum기능은 Autovacuum Daemon이라고 불리는 여러 개의 프로세스들에 의해 수행되며, 이 중 Autovacuum Launcher 프로세스는 Worker 프로세스를 관리하고 지시하는 역할을 수행합니다.
Autovacuum이 동작하기 위해서는 AUTOVACUUM
, TRACK_COUNTS
Parameter가 켜져 있어야 합니다.
이때 Autovacuum Launcher 프로세스는 AUTOVACUUM_NAPTIME
(Sec)을 주기로 최대 AUTOVACUUM_MAX_WORKERS
개수만큼의 Worker 프로세스를 깨워서 Vacuum작업을 수행하게 됩니다.
Parameter | Default Value |
autovacuum | on |
track_counts | on |
autovacuum_naptime | 60 |
autovacuum_max_workers | 3 |
📌 단, Cluster 내에 한 개 이상(N)의 Database를 운영할 경우 동작 주기와 프로세스가 N개로 분산될 수 있습니다. 즉, Database를 추가하는 경우 초기 관련 Parameter의 증가도 고려해야 합니다.
Trigger
Autovacuum의 대상이 되는 조건은 테이블의 변화량이 정해진 임계치를 초과한 경우입니다.
앞서 TRACK_COUNTS
를 on으로 설정해야 하는 이유가 여기 있는데, 해당 Parameter를 켰을 때 DML에 의한 변화량을 추적할 수 있으며 이를 기반으로 Autovacuum의 대상 여부를 판별할 수 있기 때문입니다.
TRACK_COUNTS
를 킨 상태에서 Table의 전체 Row수와, DML발생량을 조회하는 방법은 다음과 같습니다.
# 총 Row 수 조회
select
relname,
reltuples
from
pg_class
where
relname = 'test_vm'
relname|reltuples|
-------+---------+
test_vm| 4004.0|
# DML발생량
select
relname ,
n_tup_ins , --Insert Rows
n_tup_del , --Delete Rows
n_tup_upd , -- Update Rows
last_autovacuum
from
pg_stat_all_tables
where
relname = 'test_vm'
relname|n_tup_ins|n_tup_del|n_tup_upd|last_autovacuum |
-------+---------+---------+---------+-----------------------------+
test_vm| 1001| 0| 0|2022-04-05 13:47:54.920 +0900|
이렇게 측정된 pg_stat_all_tables.n_tup_xxx
값들이 아래 공식에 의해 계산된 수치보다 높은 경우 Autovacuum의 대상으로 선정됩니다.
# Delete + Update 발생 Rows와 아래 공식 비교
autovacuum_vacuum_threshold + autovacuum_vacuum_scale_factor * pg_class.reltuples
# Insert 발생 rows와 아래 공식 비교
autovacuum_vacuum_insert_threshold + autovacuum_vacuum_insert_scale_factor * pg_class.reltuples
임계치 공식을 잘 살펴보면 INSERT
라는 키워드가 들어간 공식과 아닌 것으로 나뉘어 있습니다.
그 이유는 13 버전 이전까지 Insert조작과 관련된 Autovacuum Parameter가 존재하지 않았기 때문입니다. 즉, 13 이전 버전에서는 Delete와 Update 등 Dead Tuple이 발생하지 않는 Insert-Only Table의 경우 Autovacuum의 대상이 될 수 없는 고질적인 문제가 있었으며 Manual Vacuum을 통한 사용자 관리가 불가피했습니다.
하지만 13 버전부터 등장한 Parameter인 AUTOVACUUM_VACUUM_INSERT_SCALE_FACTOR
, AUTOVACUUM_VACUUM_INSERT_THRESHOLD
덕분에 Insert-Only Table 역시 Autovacuum에 대한 Trigger가 가능해졌습니다.
Parameter | Default Value |
autovacuum_vacuum_scale_factor | 0.2 |
autovacuum_vacuum_threshold | 50 |
autovacuum_vacuum_insert_scale_factor | 0.2 |
autovacuum_vacuum_insert_threshold | 10000 |
Anti-Wraparound Vacuum
앞서 Autovacuum을 사용하기 위한 전제조건으로 AUTOVACUUM
, TRACK_COUNTS
를 이야기했습니다. 하지만, 해당 Parameter를 Disable 시키더라도 특정 조건을 만족하는 경우 Autovacuum에 의한 자동 Vacuum은 수행될 수 있습니다.
사용자가 주기적으로 Vacuum을 수행하지도 않고, Autovacuum기능 역시 사용하지 않는 환경이 있다고 가정해 보겠습니다. 공간관리와 성능 향상이라는 Vacuum의 선한 영향력은 둘째 치더라도, Database의 정합성을 훼손시킬 수 있는 XID Wraparound 상황을 미연에 방지하기 위한 최소한의 안전장치는 필요해 보입니다.
이를 위해 PostgreSQL은 Autovacuum기능을 사용하지 않더라도 특정 상황 발생 시 Autovacuum 프로세스에 의한 Anti-Wraparound Vacuum을 자동으로 수행하게 하였으며, 해당 조건은 Table의 Age가 AUTOVACUUM_FREEZE_MAX_AGE
를 초과한 시점입니다.
AUTOVACUUM_FREEZE_MAX_AGE
는 앞서 Eager Mode와 Lazy Mode의 선택 기준으로 이야기한 VACUUM_FREEZE_TABLE_AGE
보다 큰 수치이며 XID Wraparound상황을 저지하기 위한 마지막 방어 라인으로 볼 수 있습니다.
Parameter | Default Value |
autovacuum_freeze_max_age | 200000000 |
vacuum_freeze_table_age | 150000000 |
📌 vacuum_freeze_table_age가 autovacuum_freeze_max_age보다 커질 수 있다면 Manual Vacuum의 Eager Mode는 의미가 없어집니다. 이러한 이유로 vacuum_freeze_table_age를 아무리 크게 변경해도 autovacuum_freeze_max_age의 95% 로 제한됩니다.
Autovacuum Process
Autovacuum의 동작 과정을 정리하면 아래와 같습니다. Manual Vacuum과 비슷하지만 더 많은 Parameter에 의해 제어됨을 알 수 있습니다.
Parameter | Default Value |
vacuum_freeze_min_age | 50000000 |
vacuum_freeze_table_age | 150000000 |
autovacuum_freeze_max_age | 200000000 |
autovacuum | on |
track_count | on |
autovacuum_vacuum_scale_factor | 0.2 |
autovacuum_vacuum_threshold | 50 |
autovacuum_vacuum_insert_scale_factor | 0.2 |
autovacuum_vacuum_insert_threshold | 10000 |
임계치 계산 공식
autovacuum_vacuum_threshold + autovacuum_vacuum_scale_factor * pg_class.reltuples
autovacuum_vacuum_insert_threshold + autovacuum_vacuum_insert_ scale_factor * pg_class.reltuples
기획 및 글 | 기술기획팀
이미지 제작 | 디자인그룹 이민석
'엑셈 경쟁력 > DB 인사이드' 카테고리의 다른 글
DB 인사이드 | MySQL Architecture - 2. 스토리지 엔진 (0) | 2022.06.30 |
---|---|
DB 인사이드 | MySQL Architecture - 1. MySQL 엔진 (0) | 2022.06.30 |
DB 인사이드 | PostgreSQL Vacuum - 5. Manual Vacuum (0) | 2022.04.29 |
DB 인사이드 | PostgreSQL Vacuum - 4. Visibility Map (0) | 2022.04.29 |
DB 인사이드 | PostgreSQL Vacuum - 3. Age (2) | 2022.04.29 |
댓글