PostgreSQL은 다른 RDBMS와는 다르게 Vacuum이라는 개념이 존재한다.
간단히 말하자면 더 이상 사용되지 않는 데이터들을 정리하는 명령이다.
DB에 데이터는 물리적으로 디스크에 저장되게 된다.
그러나, 이 데이터를 UPDATE or DELETE 시에 디스크에 있던 기존 정보를 갱신하거나 삭제하지 않는다.
UPDATE 과정
FSM(FreeSpaceMap)에 사용 가능한 공간이 있는지 확인, 없으면 FSM을 추가로 확보
(FSM : 사용 가능한 공간을 표시하는 Map)
FSM의 사용 가능한 공간에 update된 데이터를 기록 (Insert)
update된 데이터의 저장이 완료되면 update 이전 원본 Tuple을 가리키던 포인터를 이동
해당 과정을 거친 뒤, 기존 데이터는 어디에도 참조되지 않는 Tuple이 된다. 이 Tuple을 Dead Tuple 이라고 한다.
그렇다면 왜 이런 번거로운 작업을 수행할까?
그 이유는 PostgreSQL의 MVCC(Multi-Version Concurrency Control)구현 방식때문이다.
-> (쉽게 말하자면 Transaction을 위해 )
Transaction ID 예시
xmin | xmax | value |
---|---|---|
2010 | 2020 | AAA |
2012 | 0 | BBB |
2014 | 2030 | CCC |
2020 | 0 | ZZZ |
따라서 DB에 데이터가 변경될 수록 Dead Tuple이 많아지고, 쓸모 없는 데이터까지 page 단위로 읽어와 메모리에 올리기 때문에 성능이 저하되는 현상이 발생한다.
Vacuum, Vacuum full에 차이가 존재한다.
해결책 : pg_repack (Open Source)
-- DB 전체 풀 실행
vacuum full analyze;
-- DB 전체 간단하게 실행
vacuum verbose analyze;
-- 해당 테이블만 간단하게 실행
vacuum analyse [테이블 명];
-- 특정 테이블만 풀 실행
vacuum full [테이블명];
DB 설정으로 AutoVacuum을 OFF해놔도 관련 임계치를 초과하면 DB에서 강제로 수행하게 된다.
Tuple의 xmin, xmax를 통해 MVCC가 구현되어 있다.
약 40억개의 트랜잭션을 표현할 수 있으며, 20억개는 과거/20억개는 미래를 위해 사용하게 된다.
만약 Transaction ID가 20억이 넘어 1이 되었다면, 기존의 데이터들이 모두 미래에 있는 것 처럼 되어 보여지게 않게 된다.
이 현상을 Transaction ID Wraparound 라고 한다.
이를 방지하기 위해 특정 시점에 모두 frozen XID = 2 라는 특별한 Transaction ID로 바꿔버린다.
이 동작을 freeze 혹은 Anti Wraparound Vacuum 이라고 한다.
기본적으로 두 가지 상황에서 수행된다.
vacuum threshold = autovacuum_vacuum_threshold + autovacuum_vacuum_scale_factor * number of Tuples
Default : Dead Tuple 누적치가 테이블의 모든 행 중 20% + 50개를 초과하는 경우 AutoVacuum 이 호출되어 Dead Tuple을 정리하게 된다.
Dead Tuple 정리와 Vacuum의 부하 간 적절한 균형을 찾아야 한다.
autovacuum_vacuum_scale_factor & autovacuum_vacuum_threshold
default 설정
권장 설정
autovacuum_vacuum_cost_limit & autovacuum_vacuum_cost_delay
default 설정
권장 설정
autovacuum_vacuum_cost_limit : AutoVacuum이 한 번 수행될 때마다 갖는 credit
autovacuum_vacuum_cost_delay : 가진 credit을 모두 소모한 뒤 sleep 텀
credit이 모두 소진되면 해당 AutoVaccum 프로세스는 종료된다.
credit이 너무 작으면, Dead Tuple을 정리하지 못한 채 끝나버리기 때문에 Dead Tuple이 계속 누적된다.
요약
AutoVacuum이 너무 드물게 돌고있다
AutoVacuum이 너무 느리다
추가
우아한 테크 세미나 - PostgreSQL 모니터링 방법