코딩스토리/데이터베이스

PostgreSQL 데이터베이스 저장공간 확보하기 - Truncate, Vacuum

Tech&Fin 2022. 2. 25. 00:02
반응형

지난 포스팅까지 웹소켓을 이용하여 업비트 현재가 정보를 구독/수신하여 PostgreSQL DB에 저장하는 방법에 대해서 살펴 보았습니다.

 

PostgreSQL 데이터베이스는 무료로 사용할 수 있는 DB이긴 하지만 오라클 클라우드 프리티어 서버에서는 무료로 사용할 수 있는 디스크 용량이 최대 200G이기 때문에 데이터를 무한대로 쌓아둘 수는 없습니다.

 

이번 시간에는 PostgreSQL에서 데이터를 삭제하고 디스크 용량을 반환 받는 방법에 대해서 살펴 보겠습니다.

 

 

목차 - 클릭하면 이동합니다.

     

    현재 사이즈 확인

    현재가 테이블 데이터 사이즈 확인

    웹소켓을 이용하여 업비트에서 거래되고 있는 KRW 마켓의 모든 종목의 현재가 데이터를 구독하여 전부 저장을 진행하고 있는데요. 지금까지 쌓인 로우수와 서버에 사용되고 있는 디스크 용량에 대해서 먼저 살펴 보겠습니다.

     

    SELECT COUNT(*)
      FROM TICKER_DATA;

    대략적으로 2일 정도가 지난 듯 싶은데요. ROW COUNT를 세는 SQL 쿼리를 수행해 보니 8백만개의 로우가 저장되어 있음을 알 수 있습니다. 생각보다 많은 로우가 저장되었는데 아마도 금일 러시아의 우크라이나 침공 관련 악재로 낙폭이 커졌을 때 거래가 평소보다 많이 발생한 것으로 추정 됩니다.

     

    테이블의 컬럼 갯수가 적거나 많으면 저장 공간에 영향을 미치기 때문에 모든 테이블을 같은 기준으로 보면 안되며 저희가 생성한 현재가 테이블의 경우는 8백만개 로우(약 2일) 기준으로 3.1기가 정도의 디스크 공간이 사용되었음을 알 수 있습니다.

     

    Tech&Fin 서버의 경우 전체 공간 89G 중 79G의 공간이 사용가능한 공간으로 남아있는 상태 입니다.

     

    PostgreSQL 공간 확보하기

    PostgreSQL에서 디스크의 공간을 확보하는 방법은 몇 가지 방법이 있는데요. 오늘은 우선 간단한 방법 몇 가지를 살펴보도록 하겠습니다.

     

    VACUUM FULL

    VACUUM FULL 테이블명;

    오라클 DB와 마찬가지로 PostgreSQL에서도 DELETE 명령어를 사용하여 데이터를 삭제하더라도 실제 데이터가 저장되어 있는 디스크의 공간은 줄어들지 않습니다.

     

    DELETE 명령어를 수행해도 삭제 플래그만 달아놓고 실제 데이터를 삭제하지는 않기 때문인데요. VACUUM FULL 명령어를 사용하면 이런 공간을 삭제하고 다시 테이블을 구성하기 때문에 저장 공간을 확보할 수 있습니다.

     

    다만 사용하지 않는 공간을 제외하고 새로운 테이블을 만들고 기존 테이블을 없애는 형식의 프로세스를 사용하기 때문에 현재 사용하고 있는 디스크 공간의 두 배 이상의 공간이 필요하게 됩니다.

     

    예를 들면 현재 3G를 사용하고 있는 테이블의 일부 데이터를 삭제하고 VACUUM FULL 명령어를 수행하면 일시적으로 디스크 용량이 늘어났다가 줄어들게 됩니다. 그래서 VACUUM FULL 명령어를 사용하려면 현재 디스크 공간보다 여유롭게 1.5배 이상 공간이 남았을 때 수행해야 합니다.

     

    그럼 실제로 그런 일이 벌어지는지 한번 확인해 보겠습니다.

     

    약 2백만개의 로우를 삭제했음에도 불구하고 오히려 디스크 사용량은 3.9G로 늘어났습니다. 실제 데이터를 삭제하는 것이 아니라 변경 이력이 생성되고 삭제 플래그가 달린 공간이 계속 남아있어서 그런데요.

     

    이 상태에서 VACUUM FULL 명령어를 사용해 보겠습니다.

    VACUUM이 진행되는 동안 디스크 용량이 계속해서 증가함을 알 수 있습니다.

     

    VACUUM FULL 명령어 이후 2.8G로 용량이 줄긴 했으나 바로 적용되지는 않고 몇 시간 후에 적용이 되었습니다.

     

    VACUUM FULL 명령어를 이용하면 실제 물리적인 디스크 용량이 반환되는 것은 확인 되었으나 일시적으로 2배 가량의 디스크 용량이 사용되고 수행 즉시 디스크 용량이 반환되지 않으며 가장 큰 문제로는 VACUUM FULL 명령어가 수행되는 동안 테이블이 Exclusive Lock 상태가 되어 데이터를 저장할 수 없는 문제가 발생하게 됩니다.

     

    참고로 VACUUM FULL 이 아닌 일반 VACUUM 명령어는 물리적인 디스크의 공간을 반환하지 않기 때문에 물리적인 공간의 확보를 원한다면 트랜잭션이 발생하지 않는 시간에 VACUUM FULL 명령어를 수행해야 합니다.

     

    TRUNCATE TABLE

    TRUNCATE TABLE 테이블명;

    TRUNCATE 명령어는 테이블의 데이터를 한번에 모두 삭제하는 기능입니다. DELETE와는 다르게 명령어 수행 순간 모든 데이터가 삭제되며 디스크 공간까지 모두 즉시 반환 됩니다.

     

    명령어를 수행하자 마자 데이터가 삭제되고 디스크 용량이 116M로 줄어 들었습니다.

     

    TRUNCATE 명령어는 상당히 빠르고 간편하지만 데이터를 일부만 남기고 삭제할 수는 없고 전부 삭제만 가능합니다. 또한 다시 되돌릴 수 없기 때문에 신중하게 사용해야 합니다.

     

    마치며 

    위에서 VACUUM FULL과 TRUNCATE TABLE을 이용하여 디스크 용량을 확보하는 방법에 대해서 살펴 보았는데요. 두가지 방법 모두 지속적으로 데이터를 쌓아가기 위해서 사용하기에는 적절한 방법은 아닙니다.

     

    VACUUM FULL의 경우는 실행되는 시간동안 Exclusive Lock(Write Lock)으로 인해 데이터 Loss가 발생하고 TRUNCATE TABLE 명령어는 해당 시점에 데이터를 모두 삭제하고 새롭게 데이터를 쌓아가기 때문입니다.

     

    pg_repack이라는 extention tool을 이용하면 최소한의 Lock을 사용하여 VACUUM FULL 명령어를 사용하는 효과를 낼 수 있지만 이 방법 역시 수행되는 과정 중 짧은 시간이라도 Lock이 발생하여 트랜잭션에 대한 Loss가 발생하게 됩니다.

     

    결국 Lock 없이 테이블의 데이터를 DELETE한 후 공간을 확보하는 효율적인 방법은 아직까지는 없는 것 같습니다. 다소 불편하더라도 일정한 디스크 용량을 넘어서지 않도록 관리하며 사용하는 방법이 현재로써는 무료로 사용할 수 있는 방법이 아닐까 생각됩니다.

     

    데이터를 10일 정도치만 보관하고 주기적으로 10일 이전 데이터를 DELETE문으로 삭제한 후 VACUUM FULL이 아닌 일반 VACUUM 명령어를 사용하면 tABLE LOCK 없이 사용되지 않는 공간은 DEAD TUPLE을 다시 사용할 수 있는 공간으로 만들어 주기 때문에 실제 디스크 용량이 줄어들지는 않지만 사용한 디스크 용량이 더이상 늘어나지 않도록 할 수 있습니다.

     

    즉 아무리 데이터가 많더라 하더라도 1일에 5G를 넘어서지는 않을 것 같으니 10일치 데이터만 지속적으로 보관하고 VACUUM 명령어를 사용하면 대략적으로 최대 50~60G 정도의 공간을 사용하면서 무료로 PostgreSQL 데이터베이스 서버에 현재가 데이터를 적재하면서 사용할 수 있을 것 같습니다.

     

    블로그를 구독하시면 소식을 조금 더 빨리 받아보실 수 있습니다. 감사합니다.

    반응형

    '코딩스토리 > 데이터베이스' 카테고리의 다른 글

    PostgreSQL 도커 사용하여 설치하기  (0) 2023.11.22