ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [PostgreSQL] Vacuum
    DB/PostgreSQL 2021. 4. 4. 18:41

    pg에서는 주기적인 Vacuum이 필요합니다. Vacuum은 진공 청소기라는 뜻 그대로 더이상 사용하지 않는 데이터를 정리해주는 역할을 합니다. 즉, 디스크 조각 모음과 같습니다. pg는 다중 버전 동시성 제어(MVCC)를 지원하기 때문에 데이터의 삭제, 수정이 발생하면 더이상 사용하지 않는 여러 버전의 데이터가 존재합니다. 만약 Vacuum을 진행하지 않으면 이러한 데이터가 지속적으로 쌓여서 실제 테이블 데이터 자체는 적은데 테이블의 사이즈는 어마어마하게 커지는 것을 볼 수 있습니다. 이런 테이블은 당연히 조회 속도가 느려집니다. 또한 데이터베이스의 나이가 줄지 않아 트랜잭션 ID 겹침 현상이 발생해 auto vacuum이 freeze 상태에서 멈출 수 있습니다. 이러한 현상이 지속되면 트랜잭션 ID를 재활용하지 못해서 데이터베이스가 멈추는 상황까지 발생할 수 있습니다. 마지막으로 vacuum을 진행하면 인덱스 전용 검색 성능을 향상하는데 이용하는 실자료 지도(visibility map, vm) 정보를 갱신하는데에 도움이 됩니다.

    트랜잭션 ID 겹침이란?

    PostgreSQL에서는 트랜잭션 ID의 크기가 32bit 정수형 크기이며 하나의 서버에서 해당 크기를 넘기면 트랜잭션 ID가 겹치는 현상이 발생합니다.

    PostgreSQL에서 수정, 삭제

    다중 동시성 제어(MVCC)에서는 특정 데이터에 대해 수정, 삭제가 발생하면 물리적인 저장공간에서 원본 데이터를 지우지 않고 그대로 유지합니다. 오래된 행 중에서 어느 곳에서도 참조되지 않고 안전하게 재사용할 수 있는 행을 찾아, FSM(Free Space Map)이라는 메모리 공간에 위치와 크기를 기록합니다. 삽입이나 수정등 새로운 행을 추가할 경우 FSM영역에서 검색하여 새로운 데이터를 저장할 수 있는 row를 찾고 그곳을 재사용합니다.

    위와 같이 구조가 진행됩니다.

    vacuum을 하지 않으면 위의 수정으로 더이상 사용하지 않는(참조하지 않는) 2 이 와 같은 공간을 활용하지 못하게 됩니다. 이러한 데이터를 데드 튜플이라 합니다. 이러한 데드 튜플이 차지하는 공간을 FSM으로 반환하여 재사용을 할 수 있도록 하는 작업을 vacuum이라 합니다.

    Vacuum이 하는 일

    dead tuple을 FSM에 반환

    데드 튜플은 위에서 설명한 것처럼 수정이나 삭제로 인해 발생한 이전 버전의 데이터, 즉 어디에서도 사용하지 않는 데이터를 말합니다. 이러한 데드 튜플을 vacuum 작업을 통해 FSM에 반환하기 전까지는 그 자리에 새로운 데이터를 저장할 수 없습니다. 예를 들어, 한 10만개 row를 가지는 테이블에 update를 10만개를 했다면 10만개의 데드 튜플이 생기고 다음 작업에서 10만개를 또 update했다면 vacuum을 하지 않았기 때문에 10만개의 데드튜플이 더 생기게 됩니다. 즉, 해당 테이블은 10만개의 live tuple과 20만개의 dead tuple이 존재합니다. 여기서 vacuum을 진행하면 20만개의 데드 튜플 공간을 FSM에 반환하게 되며 다음 업데이트 부터는 해당 공간을 재활용하게 됩니다.

    즉, vacuum을 진행했다고 해서 이미 늘어난 테이블의 크기는 줄어들지 않고 재활욜할 수 있도록 처리를 해주게 됩니다. (vacuum 이전 테이블 크기 5MB, 실데이터 5MB라면 vacuum을 한 다음엔 테이블 크기 5MB, 실데이터 1MB로 4MB의 재사용 가능한 공간을 확보)

    실 자료 지도(Visibillity, Map, VM)파일의 내용을 갱신

    트랜잭션 ID 겹침 방지

    명령어

    vacuum 명령어는 다음과 같습니다.

    vacuum [full | verbose | analyze | freeze] 테이블명;

    여기서 full 옵션은 빈 영역에 tuple을 옮기는 것과 같이 디스크 최적화 작업을 진행합니다. 해당 옵션으로 진행하면 더 많은 공간을 확보하고 최적화가 잘 되지만 처리 시간이 오래 걸리며 ACCESS EXCLUSIVE 락이 걸리므로 DDL은 물론, DML도 전부 막히게 되므로 운영 중인 DB에서는 사용하지 않는 것이 좋습니다.

    다른 옵션들의 경우 단순히 점유되고 있던 공간을 사용할 수 있도록 변경하며 해당 작업동안 읽고 쓰는 것은 허용이 됩니다.

    여기서 vacuum을 주기적으로 해야 한다면 수동으로 처리하는 것 보다 auto vacuum을 사용하는 것이 좋습니다.

    댓글