PostgreSQLのVACUUM
VACUUMとは
- VACUUMとはPostgreSQL独自のSQLコマンドです。
- VACUUMはデータベース内のごみを掃除してくれます。
正確には以下の3つの効果があります。
- 更新、あるいは、削除された行によって占められた領域の復旧。
- トランザクション IDの周回による非常に古いデータの損失の防止。
- PostgreSQL問い合わせプランナによって使用されるデータ統計情報の更新。
- デフォルトでは接続しているデータベースの全テーブルに対して行います。
- テーブルを指定して行うことも出来ます。
上記3点の効果の詳細を紹介します。
更新、あるいは、削除された行によって占められた領域の復旧
- PostgreSQLは追記型といわれるアーキテクチャを取っています。
- 行を挿入した場合、どんなDBでもデータは追記されますが、PostgreSQLは更新しても追記されます。
- また、物理削除しても上図の更新前のレコード同様に残ります。
- このようにしてデータベースに変更があると、どんどんデータを追記していきます。
- データの追記を続けるうちに無駄なデータが増え、パフォーマンスに影響を及ぼします。
更新・削除により増加した不要なデータをVACUUMにより削除します。
VACUUMの種類
- FULL VACUUM
- Concurrent VACUUM
- FULL VACUUMはVACUUMコマンドに[FULL]オプションを指定して実行します。
- このFULL VACUUMを実行した場合、対象のテーブルはロックされます。(テーブルを指定しない場合、データベース内の全てのテーブルがロックされる)
- FULL VACUUMを行うと、不要領域はディスク上から削除され、データベースのディスクサイズは小さくなります。
- 一般的にはディスク容量の限界により使用する以外は使わなくても大丈夫なようです。
- PostgreSQL7.1まではFULL VACUUMしかありませんでした。バージョン7.2でこれを改善し、VACUUM中もテーブルを変更可能になりました。
- テーブルをロックしないVACUUMをConcurrent VACUUMといいます。
- オプションでFULLを指定しない限りは、VACUUMはConcurrent VACUUMで行われます。
- Concurrent VACUUMは不要領域を再利用領域とします。つまり、VACUUM前と後でデータベースのディスクサイズは変わりません。
トランザクション IDの周回による非常に古いデータの損失の防止
- 先述の通りPostgreSQLは更新時にもデータを追記します。
- この時、PostgreSQLの内部では更新前と更新後のデータが存在し続けます。
- データの状態を判断するために PostgreSQL は内部的に[トランザクションID]と言われるものを割り当てます。
- このトランザクションIDは更新の度に振られていく32bitの整数です。
- トランザクションIDを使い切った場合、1周して元に戻ってしまいます。
- もし1周した場合、先に割り当てられたトランザクションIDを重複して別のデータに割り当ててしまいます。
- この場合、後からトランザクションIDを割り当てられたデータは参照できなくなってしまいます。
- VACUUMを行うことによりトランザクションIDが初期化されます。
統計情報の更新
- VACUUMコマンドのオプションとして [ANALYZE] が指定できます。
- ANALYZEを指定することによりデータベースの統計情報を更新します。
コメント