postgres를 사용하다 보면 보이는 단어가 vaccum이다. 근데 이게 뭘 하는지 정확하게 잘 모르는 사람들이 있어서(보통 무지성 기술 선택의 결과로 postgres를 사용하거나 이미 잘 동작해서 알아볼 생각을 안해서) 정리를 해보려고 한다.(가끔 다른 RDBMS에 대한 비교나 삼천포로 빠질 확률 농후, 하지만 지식을 얻어갔죠?)

실은 이미 내 글 말고도
우아한형제들 기술블로그 와 같이 훌륭한 글들이 이미 있다.
내가 주로 참고할건 공식문서와 https://product.kyobobook.co.kr/detail/S000060603553 - postgresql 9.6 성능 이야기(광고아님. 광고였으면 좋겠음)
https://blog.ex-em.com/1667 - 우리나라에서 postgres관련 블로그 가히 원탑으로 저는 말합니다
기타 등등을 참고한다.
VACCUM?
우선 vaccum에 대한 공식 문서를 좀 봐보자.

VACUUM reclaims storage occupied by dead tuples. In normal PostgreSQL operation, tuples that are deleted or obsoleted by an update are not physically removed from their table; they remain present until a VACUUM is done. Therefore it's necessary to do VACUUM periodically, especially on frequently-updated tables.
처음부터 딱 핵심만 알려주는 너무 좋은 말이 나온다.
VACUUM을 사용해서 dead tuple이 차지한 공간을 회수한다. 일반적인 PostgreSQL이 동작하고 있는(운영되고 있는) 상황에서는 삭제되거나 업데이트 되어 더 이상 필요하지 않게 된 튜플이 '물리적으로' 제거 되지 않는다. VACUUM이 실행될때까지 남아있는다. 그래서 자주 업데이트 되는 테이블에서는 VACUUM을 특히 주기적으로 진행해야한다.
이러면 좀 궁금해진다. 왜 남아있지? 이건 이 시리즈에서 꼬리물기로 한번 다루어보겠다. 우선 하고자 하는 부분에 집중하자.
그 뒤에 글을 좀 더 읽어보면
Plain VACUUM (without FULL) simply reclaims space and makes it available for re-use. This form of the command can operate in parallel with normal reading and writing of the table, as an exclusive lock is not obtained. However, extra space is not returned to the operating system (in most cases); it's just kept available for re-use within the same table. It also allows us to leverage multiple CPUs in order to process indexes. This feature is known as parallel vacuum. To disable this feature, one can use PARALLEL option and specify parallel workers as zero. VACUUM FULL rewrites the entire contents of the table into a new disk file with no extra space, allowing unused space to be returned to the operating system. This form is much slower and requires an ACCESS EXCLUSIVE lock on each table while it is being processed.
Plain VACUUM(FULL 없이)은 단순히 공간을 회수해서 '재사용 가능'하게 만든다. 즉, 이 명령어는 기본적인 READ/WRITE와 병렬로 작동이 가능하다. 그러나 대부분의 케이스에서 추가 공간은 OS에 반환되지 않고 재사용 가능한 빈 공간으로 남아있다.
여기서 약간 단어적으로 혼동이 왔었는데 extra space라는건 VACUUM을 통해 재사용 가능하게 만들어진 공간(space)를 의미하고 있다.
만약 OS레벨에서, 새 디스크 파일로 재기록하여 사용되지 않는 공간을 반환하게 만들고 싶다면(물리적으로 하드디스크 용량을 확보하고 싶다면) VACUUM FULL을 사용하면 된다. 단, 이 작업은 각 테이블에 대해 ACCESS EXCLUSIVVE LOCK이 필요하다.(즉 병렬로 처리가 불가능하며 해당 작업을 하는 동안 해당 테이블에 접근을 못하니 함부로 돌리면 안된다는 뜻)
DEAD TUPLE?
어 근데 이제 슬슬 정말 의문을 해소할 순간이 왔다. 도대체 dead tuple은 왜 생기는가?
이걸 알기 위해 우리는 PostgreSQL의 MVCC에 대해 알아볼 필요가 있다.
우선 MVCC란 Multiversion Concurrency Control의 약자로 쉽게 말하면 DBMS상에서 여러 트랜잭션이 동시에 READ/WRITE를 해도 서로 간섭 없이 동작하도록 하는 동시성 제어 기법이다. PostgreSQL에서는 이 MVCC를 각 ROW에 대해 여러 버전(version = tuple)을 만드는 방식을 차용했다. 즉, 새로 row가 업데이트 된다면 없어지는게 아니라 tuple version update가 되는 것이다.
이미지 출처 : https://www.cs.cmu.edu/~pavlo/blog/2023/04/the-part-of-postgresql-we-hate-the-most.html
이제 우리는 하나의 row에 대해 여러 tuple이 생길 수 있다는 것을 알았다. 그러면 이제 이 tuple이 그 어디에서도 사용되지 않는 tuple이 생기게 되는데 이걸 dead tuple이라고 한다. 이 dead tuple은 자동으로 제거되지도 않고 회수되지도 않는다.(FSM에 대해서는 나중에 간략하게 정리해보도록 하자)
좋다. 이제 어느정도 VACUUM과 VACUUM FULL에 대해서 알았다. 그러면 AUTOVACUUM은 무엇인가?
GC가 있는 언어를 다루어보았다면 어느정도 heap space가 차거나 trigger되었을때 GC가 발생하는 것을 보았을 것이다. 비슷하게 trigger가 걸려 VACUUM이 자동 수행되는걸 AUTOVACUUM이라고 한다.(문제는 DB에서는 AUTOVACUUM 옵션을 꺼두어도 threshold를 넘어서면 강제로 DB에서 진행함)
2편에서 계속
velog에서 똑같은 글을 본다면 제 다른 블로그가 맞습니다.
'컴퓨터공학 > 데이터베이스' 카테고리의 다른 글
| PostgreSQL 9.6 성능 이야기 1장 : 아키텍처 개요 (0) | 2024.03.31 |
|---|---|
| UUID에 바로 LIKE연산자를 사용하려고 했더니 안되었던 이유는? (1) | 2024.02.04 |
| postgresql9.6 성능 이야기 1장 - 아키텍처 개요를 보다가 (1) | 2024.01.27 |
| postgres가 어느 날 맛이 가버렸다. postmaster는 뭐고 왜 이런 일이 발생했을까 (0) | 2024.01.20 |
| PostgreSQL Materialized View 사용기 (1) | 2024.01.12 |