Milky's note

[PostgreSQL] Vacuum 수행 본문

SQL/요약 정리

[PostgreSQL] Vacuum 수행

밀뿌 2022. 1. 5. 17:52

1. 성능저하의 원인

지금 운영 중인 시스템에서 로그 쌓는 DB를 AWS RDS PostgreSQL을 사용하고 있다.
모니터링하는 시스템이다보니 인터페이스가 될 때마다 많은 양의 로그가 테이블에 Insert, Update 되고 있다.
PostgreSQL은 Update 과정이 생겨도, 디스크 상의 해당 Row를 물리적으로 업데이트하지 않고, 새로운 영역을 할당해서 사용하고 있다.
그래서 이런 과정(테이블에 Update)을 거치면서, 기존에 있던 영역들은 Dead Tuple로 발생하게 된다.

PostgreSQL에서 모든 데이터는 Tuple로 저장되는데, 모든 Tuple은 live Tuple와 dead Tuple로 나뉘어진다.
Dead Tuple은 더 이상 사용되지 않는 Tuple이다. 


Dead Tuple이 많아질 수록 다음과 같은 문제가  생기게 된다.
1. 디스크 I/O 증가로 인한 성능 저하
2. 불필요한 인덱스 증가
3. 데이터 팽창


2. vacuum이란?

위와 같은 이유들로 인해, PostgreSQL에는 vacuum이라는 기능이 존재한다.
vacuum이란, 영어로 해석하면 진공 청소기라는 뜻이다.
뜻에서도 알 수 있듯이, 사용하지 않는 공간인 dead Tuple들을 청소해주는 명령어이다.

 


하지만 PostgreSQL 사용자여도 모를 수도 있다. 

왜냐하면 PostgreSQL에는 자동으로 vacuum을 해주는 auto_vacuum 기능이 있기 때문이다.
vacuum을 해주기 귀찮거나 번거롭다면, auto_vacuum의 주기를 수정하여 auto_vacuum에 맡겨도 된다.
그렇다면 auto_vacuum의 기능을 사용자 환경에 맞게 커스텀할 수 있을까? 당연히 있다!!!!!!!!!!!!!!!!

auto_vacuum의 기능을 수정하려면 postgresql.conf 파일이나 쿼리를 사용해서 수정하면 된다.

  • autovacuum_vacuum_threshold : vacuum 이 일어나기 위한 dead Tuple 의 최소 갯수 (default : 50)
  • autovacuum_vacuum_scale_factor: vacuum 이 일어나기 위한 live Tuple 대비 dead Tuple 의 최소 비율  (default : 0.2)
--파라미터 확인
select context,name,setting from pg_settings 
where name in ('autovacuum_vacuum_scale_factor', 'autovacuum_vacuum_threshold');
-- auto_vacuum 설정 변경
alter table [Table 명] set (autovacuum_vacuum_scale_factor = 0);
alter table [Table 명] set (autovacuum_vacuum_threshold = 100000);


위 두 파라미터를 통해 Autovacuum 동작 주기를 설정할 수 있다.

 

Autovacuum 동작 주기를 계산하는 식은 다음과 같다.

 

Autovacuum 동작 주기 : (테이블 row수 * autovacuum_vacuum_scale_factor) + autovacuum_vacuum_threshold

 

즉, dead Tuple가 위의 계산한 값 이상으로 발생되면 Autovacuum을 수행한다.

-- dead Tuple, live Tuple 확인
SELECT relname, n_live_tup, n_dead_tup FROM pg_stat_user_tables;
-- vacuum, autovacuum를 수행한 가장 최근 시각과 횟수 조회
select relname, last_vacuum, last_autovacuum, vacuum_count, autovacuum_count 
FROM pg_stat_user_tables;

 

3. vacuum 수행

이제 vacuum을 하는 이유와 설정하는 법을 알았으니 수행하면 된다.
vacuum을 수행하는 쿼리는 다음과 같다.
여기에서 꼭꼭 진짜 정말 주의할 점이 한 가지 있는데,
full 옵션으로 실행시 데이터베이스에 lock이 걸리므로 운영중인 데이터베이스에서는 해당 옵션을 지양하고 있다.

 

-- DB 전체 full vacuum
vacuum full analyze;

-- DB 전체 간단하게 실행
vacuum verbose analyze;

-- 해당 테이블만 간단하게 실행
vacuum analyze [Table 명];

-- 특정 테이블만 full vacuum
vacuum full [Table 명];



이상 vacuum에 관하여 정리를 해보았다.
사실 어제 아침7시에 로그를 테이블에 쌓다가 OOM이 발생하였다.... 하....
다행히 이중화를 해놔서 큰 문제도 없고 지장도 없었는데, 그래도 일단 서버가 한번 멈춰서 짜증이 났다ㅜ
급하게 Heap 메모리도 올리고, vacuum도 수행하였다.
Heap Dump를 받아서 분석하다가 vacuum도 한 번 더 정리할 겸 마음 다잡으면서 정리했다.
다시는 장애가 나질 않길 바라며😂

내일은 PostgreSQL 파티셔닝에 대해서 정리해야겠당!

'SQL > 요약 정리' 카테고리의 다른 글

[K-Digital] 데이터 모델링  (0) 2022.05.18
[PostgreSQL] Table Partitioning  (0) 2022.01.06
[PostgreSQL] Window Function  (1) 2021.11.29
Comments