DBA의 길

Postgres - vacuum .. 은 메모리를 청소하지 않아

모모토 2024. 10. 15. 01:08
반응형

postgres 에서 MVCC(Multi Version Concurrency Control) 을 위해서 독특한 기능이 존재하는데 바로 VACUUM이다.
그런데 필자도 그렇고 주변에 vacuum에 대해서 오해하는 경우가 더러 있는 것 같았다. vacuum이 메모리를 청소하는가?
아니다 vacuum 과 메모리 확보는 상관관계지 원인과 결과가 아니다.
 

24.1.2. Recovering Disk Space 


In PostgreSQL, an UPDATE or DELETE of a row does not immediately remove the old version of the row. This approach is necessary to gain the benefits of multiversion concurrency control (MVCC, see Chapter 13): the row version must not be deleted while it is still potentially visible to other transactions. But eventually, an outdated or deleted row version is no longer of interest to any transaction. The space it occupies must then be reclaimed for reuse by new rows, to avoid unbounded growth of disk space requirements. This is done by running VACUUM.

https://www.postgresql.org/docs/current/routine-vacuuming.html

 
vacuum 은 disk에서 dead tuple 을 정리한다. 이 dead tuple 은 MVCC 동시성 제어를 위하여 생기는데 위 postgres 공식문서에서 확인 할 수 있듯이 UPDATE , DELETE 시에 기존의 tuple을 old version으로 남겨두고 UPDATE 일땐 새로운 tuple , new version , 로 복사한다. DELETE 라면 new version 없이 제거일 것 이다.
 
해당 record에 대한 select 요청이 온다면 DM 쿼리가 잡고있는 트랜잭션이 끝나고 commit 이 될 때까지는 old version 을 참조하게 된다. 이러한 원리로 MVCC를 유지할 수 있다. 이 모든 과정이 shared buffer 에서 이뤄진다.
 
수정이 발생하였으나 디스크에 기록되지않은  페이지를 Dirty page라 부르며 2가지 경우에 disk 에 기록이 된다. 하나는 check point 발생시 다른 하나는 버퍼 교체 알고리즘에 의해서 교체될 때이다.

update 된 tuple에 의해서 Dead tuple이 생긴 dirty page

 
check point로 인한 디스크 쓰기와 알고리즘에 의한 교체는 목적이 다르다. 플러시는 메모리의 수정된 데이터를 디스크로 단순히 저장하는 과정일 뿐, 데이터 구조 자체에는 변화를 주지 않으며 이 과정에서는 죽은 튜플도 여전히 디스크에 기록된다. 디스크에 기록된 페이지의 dead tuple은 vacuum에 의해서 청소가 되지만 memory와 동기화되지는 않는다. 정확히 이야기하자면 동기화는 일어나지만 vacuum 이 실행하는건 아니고 Postgres 자체의 캐시관리 시스템을 인하여 일어나지만 disk의 dead tuple을 제거한다고 무조건 동기화가 되지않고 메모리에는 남을 수 있다. 따라서 vacuum은 메모리와는 직접적으론 무관하며 disk에서 vacuum이 일어나도 버퍼에는 여전히 dead tuple이 존재하여 메모리를 점유 할 수 있다.

Vacuum의 역할에 대해서 GPT와 검증도중 혼동을 일으키는 AI를 바로 잡았다.


 
따라서 존재하는게 페이지 교체 알고리즘이다. postgres에서는 C언어로 구현된 모듈인 Buffer manager가 Clock-sweep 알고리즘을 사용하여 페이지 교체를 진행한다. 사용하지 않는 오래된 페이지를 디스크로 내려보내고 메모리를 비운다. 이 Clock sweep이 LRU와 비슷하다. 아래의 그림은 메모리에서 생성된 dead tuple이 vacuum에 의하여 제거되는 과정이다.
 
 

1. Clock Sweep에 의해서 사용이 적은 페이지가 디스크에 기록됨

 

2. buffer에 새로운 페이지가 교체됨으로써 메모리 확보

 

3. VACUUM이 disk의 dead tuple을 정리하여 디스크 공간 확보