본문 바로가기

PostgreSQL & EPAS

PostgreSQL Manual Vacuum Tuning

글을 작성하기 전에

Vacuum은 PostgreSQL의 MVCC 구현 방식으로 인해 필수적이며, 기본적으로 Manual Vacuum 외에 autovacuum process에 의해 수행됩니다.(off로 설정되어 있어도 autovacuum_freeze_max_age가 넘어서게 되면 자동 수행)

그러나 작성자가 운영하는 서비스에서는 autovacuum parameter 변경을 통해서 빈공간회수와 Transaction ID Wraparound(TXID 겹침)이 해결 되지 않아 manual Vacuum 을 수행하였는데 그로 인한 Vacuum의 부하와 그를 줄이는 방법에 대해 정리하겠습니다.

추후 Vacuum 장애 History 포스팅에 해당 포스팅을 링크로 달아 놓겠습니다.

 

PostgreSQL Manual Vacuum Tuning 

버전이 증가함에 따라 Vacuum 프로세스가 발전해왔으며, autovacuum을 통한 관리가 불가할 시 운영자의 개입이 필요

PostgreSQL Vacuum Histroy

- autovacuum 도입 ( PostgreSQL 8.1 ~)

- autovacuum Default가 on으로 설정 (8.3 ~)

- Visibilty Map 도입 (8.4 ~)

- Visibilty Map 에 All_frozen Bit 추가 (9.6~)

- Vacuum에 Index_cleanup 비활성화 가능(12~ )

- Parallel vacuum 도입 (13~)

 

Manual Vacuum의 목적

PostgreSQL 운영자는 크게 3가지 목적을 위해 Manual Vacuum을 수행한다( Analyze 옵션 제외) 

1. 빈공간 회수 작업

2. TXID 겹침 방지

3. VM 갱신 작업

 

Vacuum이 수행되는 순서

Vacuum public.x 를 수행하게 되면 다음과 같은 순서대로 수행된다.

1. 설정된 maintenance_work_mem를 활용해 빈공간을 회수해야할 페이지의 Tuple들의 물리적인 위치를 저장(ctid)

2. pulbic.x 의 인덱스 Vacuum

3. public.x 테이블 Vacuum 

 

위의 내용처럼 VM을 참조하여 물리적인 위치를 maintenance_work_mem에 저장해야 하므로 대용량 테이블의 Vacuum 작업은 Disk I/O를 다량 발생 시킬 수 밖에 없다.

 

* 상세) PostgreSQL 공식 홈페이지 Vacuum Phases(Ver 14)

 

그렇다면 Vacuum을 효율적으로 수행하려면 어떻게 해야할까??

기존 서비스에 영향을 주지 않으면서, 가용가능한 모든 자원을 통해 짧은 시간 내 수행되어야 한다.

 

Vacuum 성능 향상 방안

- 테이블 사이즈 줄이기

Manual Vacuum 대상 테이블은 하나의 프로세스(세션)으로 수행되기 때문에 대용량의 테이블의 경우 매우 오랜시간이 걸린다. 대용량 Heap 테이블의 경우 파티션 테이블의 전환을 통해 이를 개선해야한다.

 

- 불필요한 인덱스 갯수 줄이기

앞서 테이블 사이즈를 줄였다면, 불필요한 인덱스의 갯수를 줄이는 것을 검토해야한다. 테이블 Vacuum의 경우 VM을 통해 All_visible 된 페이지를 Skip 할 수 있으나 인덱스의 경우 Skip이 불가하다. 따라서 미사용 인덱스를 삭제해야 vacuum 의 성능향상이 이루어진다.

 

- 향상된 Vacuum 적용을 위한 DB 업그레이드

PostgreSQL 새로운 버전이 릴리즈됨에 따라 History 내용 처럼 향상된 Vacuum 이 적용되었다. 9.6버전에서의 VM all_frozen bit 적용으로 인해 Freeze 옵션 적용시에도 모든 페이지에 대해 검사하는 것이 아닌 all_frozen 된 페이지를 스킵할 수 있었으며, 13버전 Parallel Vacuum 도입으로 비약적인 Manaul Vacuum 향상을 할 수 있었다.

 

- Maintenance_work_mem 증가시키기

Vacuum 수행되는 순서 중 첫번째에서 빈공간을 회수해야할 페이지의 TID를 저장할 수 있는 만큼 Maintenace_work_mem 가 크지 않을 경우 Vacuum Index를 여러번 수행하게 된다. 그러므로 불필요한 Vacuum Index 를 줄이기 위해서는 Manual Vacuum 시의 파라미터 값을 증가 시켜 수행함으로 써 성능 향상을 이룰 수 있다.

 

 

(그림 출처 및 참고 자료)

 

postgresql.org

https://www.youtube.com/watch?v=qCGF7-zWVuI