본문 바로가기
엑셈 경쟁력/DB 인사이드

DB 인사이드 | PostgreSQL Vacuum - 6. Autovacuum

by EXEM 2022. 4. 29.

📢 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

 

기획 및 글 | 기술기획팀

이미지 제작 | 디자인그룹 이민석

 

 

 

 

댓글