2007.10.18 22:56

JDBC로 LargeObject를 업로드하는 코딩을 테스트하는데 500MB짜리 파일을 여러 개 올리고 지우는 테스트를 반복하다 보니, 어느새 /data의 크기가 80기가를 넘어가고 있더군요.
그래서 JDBC의 LargeObject를 지우는 API를 이용해서 파일을 지웠으나 여전히 용량을 그대로.

VACUUM 이라는 기능이 있더군요. 이 기능과 관련하여 구글을 검색하다 보니 MySQL과 PostgreSQL을 비교해놓은 MySQL vs. PostgreSQL 라는 글이 있군요. 저 글이 2002년 6월에 쓰여 졌으니, 현재는 각 데이터베이스에서 어떤 기능들이 더 구현되었는지 확인해야 겠지만, 저때만 해도 PostgreSQL에는 구현되어 있으나, MySQL에는 구현되지 않은 기능들도 많이 있군요.(그러나 MySQL은 빠릅니다)
어쨌거나 MySQL은 데이터베이스를 VACUUM을 이용해 청소할 필요가 없고, PostgreSQL은 VACUUM을 실행해 주어야 한다는 군요.

일단 PostgreSQL 8.2.5 Documentation의 VACCUM 항목을 보면

-이름
VACUUM 쓰레기 수집기 / 선택적으로 데이터베이스 분석하기

-개요
VACUUM [FULL] [FREEZE] [VERBOSE] [ table]
VACUUM [FULL] [FREEZE] [VERBOSE] ANALYZE [ table [ (column [, ...] ) ] ]

-설명
VACUUM 은 삭제된 tuple들이 차지하고 있는 공간을 반환합니다. 보통의 PostgreSQL 작업에서 삭제되거나 update에 의해 쓸모 없어진 tuple들은 테이블에서 물리적으로는 삭제되지 않고 VACUUM이 실행될 때까지 남아있습니다. 그러므로 VACUUM은 주기적으로 실행되어야 하며, 자주 업데이트 되는 테이블들의 경우는 더 그렇습니다.

매개변수 없이 VACUUM을 실행하면, 현재 데이터베이스의 모든 테이블에 대해서 실행합니다. 그리고 table을 매개변수로 지정하면 해당 테이블에 대해서만 실행됩니다.

VACUUM ANALYZE 는 먼저 VACUUM하고, 그 테이블을 ANALYZE합니다. ANALYZE는 해당 영문글 참조.

FULL 옵션 없이 VACUUM을 실행하면 단순히 점유되고 있던 공간은 반환하고, 다시 사용할 수 있도록 합니다. 이 작업은 테이블을 읽고 쓰는 일반적인 작업과 동시에 진행할 수 있으며, 독점적인 잠금은 포함되지 않습니다. VACUUM FULL는 각 테이블이 더 작은 수의 디스크 블럭을 유지하도록 하기 위해 tupte를 옮기는 등의 더 많은 작업을 하게 됩니다. 당연히 더 느리게 실행되며, 실행되는 동안 table에 독점적인 잠금을 겁니다.

-매개 변수
FULL
더 많은 공간을 확보하려면 FULL을 사용하시오. 그러나 더 오래 걸리고, 독점적인 잠금을 테이블에 걸게 됩니다.

FREEZE
freezing, age 등의 개념이 뭔지 잘 모르기 때문에 패스 패스 ㅜ.ㅜ

VERBOSE
각 테이블에 대한 상세한 vacuum 동작의 보고를 해 줍니다.

table
vacuum을 실행할 테이블을 지정하게 되고, 기본적으로 현재 데이터베이스의 모든 테이블이 기본값입니다.

column
analyze할 열을 지정합니다. 기본값은 모든 열입니다.

-출력
VERBOSE가 매개변수를 지정되면, VACUUM은 실행에 따른 메시지들을 출력합니다.

- 주의 사항
VACUUM은 트랜잭션 구간내에서 실행될 수 없습니다.

실제 상황에서는 거의 매일 밤 VACUUM을 실행하는 것을 추천합니다. 많은 수의 열을 지우고 더하고 난 뒤에는 해당 테이블에 대하여 VACUUM ANALYZE를 실행하는 것이 좋습니다. 이것은 모든 최근 변환에 대한 결과를 system catalog에 업데이트해서 PostgreSQL query planner 가 planning queries를 할 수 있도록 합니다.( PostgresQL query planner는 또 뭐죠ㅜㅜ )

FULL 매개변수는 일상적으로 사용되지는 않지만  특별한 상황에서는 유용할 수 있습니다. 그 한 예는 어떤 테이블의 거의 모든 열을 삭제하고, 그 테이블이 더 작은 디스크 공간을 점유하도록 축소시키기 위하기를 원할 때 입니다. 보통 VACUUM FULL이 점유한 공간을 더 축소시켜줍니다. FULL 옵션은 인덱스들을 축소시켜주지는 않습니다. 주기적으로 REINDEX를 실행시켜 주는 것이 좋습니다. 사실, 모든 인덱스들을 삭제하고, VACUUM FULL을 실행한 다음, 인덱스를 다시 만드는 것이 빠를 때가 있습니다.

VACUUM은 실질적인 I/O 트래픽을 증가시키고, 실행되고 있는 다는 세션들의 성능을 저하시킬 수 있습니다. 그러므로 비용 기반의 vaccum 지연 특징들을 사용하는 것이 좋습니다. Section 17.4.4 를 보라네요.

그리고 autovacuum을  사용할 수 있습니다. 더 자세한 정보는 Section 22.1을 보라네요.

네~ 그렇습니다. VACUUM을 실행해야 하는 군요.
자 이제 본론으로 들어가서
pgAdmin III을 실행시키고 데이터베이스에 접속하면, 데이터베이스 항목에 만들어져 있는 데이터베이스들이 보이고, 각 데이터베이스 밑에 Catalog와 Schemas항목이 있습니다.
PostgreSQL에 LargeObject를 업로드 하게 되면, pg_largeobject라는 테이블에 bytea 데이터로 들어가게 됩니다. LargeObject를 업로드 하시고, 이 테이블을 확인하시면 업로드 할 때 받은 oid로 데이터들이 들어가 있는 것을 확인할 수 있습니다.
VACUUM을 이 테이블에 대하여 실행해야 물리적으로 LargeObject를 지울 수 있습니다.
Posted by 나야

댓글을 달아 주세요