MSSQL, MySQL에 이어 이번엔 PostgreSQL 데이터 용량 줄이는 방법을 작성한다. 기본적으로 RDBMS에서 데이터베이스 파일 용량을 줄이는 원리는 비슷한 거 같다.
PostgreSQL에서는 ./data/base 경로에 있는 숫자로 된 폴더들 안에 데이터베이스 파일이 생성된다. 이 용량을 줄여야 한다. postgresql은 다른 RDB 와는 다르게 OS에 있는 파일 이름만 보고 테이블을 구분하긴 어렵다.
PostgreSQL 데이터 용량 줄이기
반복 쿼리를 이용해 TEST 테이블에 A라는 문자열로 600G, B라는 문자열로 600G 정도의 데이터를 insert 했다.
DO $$
DECLARE
i INT := 0;
BEGIN
WHILE i < 512000 LOOP
INSERT INTO TEST (TEXT) VALUES (REPEAT('A', 1024));
i := i + 1;
END LOOP;
END $$;
리눅스에서 postgresql 데이터베이스 기본 저장 경로는 /var/lib/pgsql/{버전}/data/base 다.
내 경우엔 앞서 리눅스 PostgreSQL 데이터 경로 변경 방법 글을 쓰면서 실습으로 경로를 옮겨 놓은 상황이라 /home/postgres/data/base 경로에 데이터를 생성하고 있다.
[root@localhost base]# pwd
/home/postgres/data/base
[root@localhost base]# ls
14187 16386 22577 22590 22591 22592 22593 22594 pgsql_tmp
[root@localhost base]# du -sh
1.3G .
os에 postgresql 데이터베이스 용량이 1.3G를 차지하고 있다.
1. truncate
postgresql에서도 역시 가장 추천하는 건 truncate이다.
빠르고 쉽고 깔끔하게 테이블과 디스크를 동시에 비워준다. where 절을 쓸 수 없기 때문에 데이터를 선별적으로 삭제할 수 없는 점은 동일하다.
truncate table test;
[root@localhost base]# du -sh
106M .
truncate 후 디스크 용량이 줄어든 걸 볼 수 있다.
2. vacuum full
MSSQL로 치면 shrink 역할을 하는 게 postgresql에서는 vacuum full 이다. delete한 dead tuple을 정리하고 실제 디스크 공간에 여유를 만들어 준다.
다만 이 쿼리를 날릴 땐 테이블에 락이 걸리는 점은 알아둬야 한다. 연결된 WAS가 있으면 중지하고 작업하는 게 좋다.
다시 데이터를 채우고
[root@localhost base]# du -sh
1.3G .
테이블 용량의 절반을 delete 한다.
delete from test where text like '%B';
600MB delete 하는데 대략 18초쯤 걸렸다. 개인적으로 실습해보면서 postgresql의 쿼리 처리 속도가 비교적 괜찮다고 느꼈다. delete 보다도 특히 insert 할 때 mysql 보다 3배 이상 빨랐다.
[root@localhost base]# du -sh
1.3G .
delete 이후에도 여전히 디스크 용량은 동일하다.
이제 test 테이블을 vacuum full 한다.
VACUUM FULL test;
delete 한 데이터만큼 디스크 용량이 정리된 걸 볼 수 있다.
[root@localhost base]# du -sh
678M .
경우에 따라 vacuum full 말고 vacuum 만써도 디스크 공간이 회수되기도 하는데 이건 말그대로 경우에 따라 그렇다고 한다.
vacuum이 속도가 vacuum full 보다 훨씬 빠르기 때문에 vacuum만 하고 싶은 충동이 들 수도 있긴 한데 애초에 디스크 공간 회수가 목적이면 그냥 좀 더 걸리더라도 vacuum full을 쓰는 게 정석이다.
마지막으로 똑같은 얘기를 하게 되는데 1.2G 정도 되는 귀여운 수준으로 테스트를 해서 쉬워 보이는 거지 실제 운영 환경에서 수백기가, 수테라 테이블에 이 작업 하려고하면 만만한 게 아니다. 그러니까 꼭 작업 전 걸릴 수 있는 소요 시간을 가늠 해보는 게 좋다.