postgresqlのvacuume文を初めて知った

経緯

postgresqlであるテーブルに15万件のデータ登録したときに、ディスクのデータサイズがどれだけ増えるか検証したかった。
おおよそのデータ量が知りたかったので、手順はデータをinsertして、du コマンドで /var/lib/pgsql/ の容量を確認する方法をとった。

du -s /var/lib/pgsql/

insertしたデータをdeleteしてもデータ量がへらない!?

何回か検証してるうちに、deleteしてもデータ量が減らないことに気づいた。


手元にあったPostgreSQL全機能リファレンスを読んでみると以下のようなことが書いてありました。

PostgresSQLは追記型のデータ管理を行っています。
追記型とは、データの挿入(INSERT)だけでなく更新(UPDATE)のときも、古いデータを無効にするだけで実際のデータ更新は行わず、新たにデータを追加するデータ管理方法です。


つまり、データは常に追記され無効(削除された)なデータは論理的に削除されるだけで物理的なデータは残っているらしい。

そこで、無効なデータを再利用するために使用するのがvacuume文またはvacuumedbコマンド。

vacuumedbコマンドを使ってみる

/var/lib/pgsql/ の容量を確認。

[suusuke@centos ~]$ du -s /var/lib/pgsql/
64220 /var/lib/pgsql/

15万件のデータをinsert。

[suusuke@centos ~]$ psql sampledb suusuke -f ~/insert_data.sql

再度、/var/lib/pgsql/ の容量を確認。

[suusuke@centos ~]$ du -s /var/lib/pgsql/
143340 /var/lib/pgsql/

15万件のデータをdelete後、/var/lib/pgsql/ の容量を確認。

[suusuke@centos ~]$ du -s /var/lib/pgsql/
143340 /var/lib/pgsql/ ← delete後も変わらない

vacuumedbコマンドを使用後、/var/lib/pgsql/ の容量を確認。

[suusuke@centos ~]$ vacuumedb -a
vacuumdb: vacuuming database "postgres"
VACUUM
vacuumdb: vacuuming database "sampledb"
VACUUM
vacuumdb: vacuuming database "template1"
VACUUM
[suusuke@centos ~]$ du -s /var/lib/pgsql/
143340 /var/lib/pgsql/

オプションの -f をつけないと再利用対象にはなるが、開放はしないらしいので -f をつけて再度実行。

[suusuke@centos ~]$ vacuumedb -af
vacuumdb: vacuuming database "postgres"
VACUUM
vacuumdb: vacuuming database "sampledb"
VACUUM
vacuumdb: vacuuming database "template1"
VACUUM
[suusuke@centos ~]$ sudo du -s /var/lib/pgsql/
118540 /var/lib/pgsql/ ← 開放された


また、バージョン7.2からはFSM(Free Space Map)という共有のメモリ領域を確保し、そこで再利用可能な領域の管理をしているらしい。

追記

ネットで調べてたら、本と同じ内容のサイトを発見^^
PostgreSQL関連情報


プランナとオプティマイザのところが、わかりやすく詳しく書いてある。