PostgreSQLの「お掃除係」、オートバキュームと仲良くなるための技術論
こんにちは。現場でPostgreSQLと格闘している皆さん、いかがお過ごしですか?
今日は、DBエンジニアなら避けては通れない、でも意外と誤解されがちな「オートバキューム(autovacuum)」について、少し深い話をしようと思います。
「オートバキュームが走るとパフォーマンスが落ちるからオフにしたい」
「とりあえず全部デフォルト設定で放置している」
もしそう思っているなら、ちょっと待って。オートバキュームは敵じゃありません。むしろ、適切に付き合えば最強の相棒になってくれる、データベースの「心臓部」を支える重要な仕組みなんです。
—
なぜオートバキュームが必要なのか?(MVCCという宿命)
まず、PostgreSQLのアーキテクチャのお話をしましょう。PostgreSQLはMVCC(多版同時実行制御)という仕組みを採用しています。
例えば、あるレコードを `UPDATE` したとき、PostgreSQLは古いデータを物理的に削除するのではなく、「古いデータは無効(デッドタプル)」としてフラグを立て、新しいレコードを別の場所に書き込みます。
この「ゴミ」を放置するとどうなるか?
- テーブルが肥大化する(ストレージを圧迫する)
- スキャン速度が落ちる(ゴミの中をかき分けてデータを探す羽目になる)
- インデックスも肥大化する(結果、インデックス検索が遅くなる)
このゴミを片付け、統計情報を更新してプランナに最新の状況を伝えるのが、オートバキュームワーカーの仕事です。
「設定値、いじってますか?」
デフォルトの設定は非常に「保守的」です。小規模なDBなら良いのですが、トランザクションが活発な環境では、デフォルトの設定だと「ゴミの蓄積スピード」に「片付け」が追いつきません。
特に見てほしいのは、`postgresql.conf` のこれらの値です。
おすすめの調整ポイント
autovacuum_vacuum_scale_factor = 0.05 # デフォルトは0.2(20%)
autovacuum_analyze_scale_factor = 0.02 # デフォルトは0.1(10%)
なぜここを調整するのか?
デフォルトの `0.2` だと、テーブルが100万行ある場合、20万行更新されるまで掃除が始まりません。これだと「重い掃除」が長時間走ることになり、システム全体に悪影響が出ます。
`0.05` くらいに下げて「こまめに掃除する」ほうが、結果的に負荷が平準化され、パフォーマンスも安定するんです。
「バキュームが追いつかない!」を防ぐために
実務で一番怖いのは、オートバキュームが追いつかず、テーブルが肥大化し続けるケースです。これを監視するには、以下のクエリが役に立ちます。
SELECT
relname AS table_name,
n_dead_tup,
last_autovacuum,
last_autoanalyze
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC;
もし、`n_dead_tup`(デッドタプル数)が異常に増えているテーブルを見つけたら、まずはそのテーブルの統計情報を確認してください。
先輩からのアドバイス:運用で気をつけるべき「3つの鉄則」
1. バキュームを「悪」だと思わない
「バキュームが走ると重くなる」と嘆く前に、そのバキュームが何分かかっているかを計測してください。数秒で終わるなら、それは健全な証拠です。本当に問題なのは、バキュームそのものではなく「肥大化したテーブルをフルスキャンしていること」かもしれません。
2. ストレージの速度を考慮する
最近は高速なSSDが当たり前ですが、I/O性能が低い環境でオートバキュームを過剰に働かせると、確かにシステムは重くなります。その場合は `autovacuum_vacuum_cost_limit` を調整して、バキュームが一度に消費するコスト(負荷)を制御してあげましょう。
3. 「手動バキューム」は最後の手段
オートバキュームが追いつかないからといって、すぐにcronで `VACUUM` を叩くのは少し待って。まずはテーブルごとの設定を見直しましょう。
— 特定のテーブルだけバキュームの閾値を下げる(これ重要!)
ALTER TABLE target_table SET (autovacuum_vacuum_scale_factor = 0.01);
最後に
オートバキュームは、データベースを「長持ち」させるためのメンテナンス作業です。車で言えばオイル交換やタイヤの空気圧チェックのようなもの。面倒に感じるかもしれませんが、これをサボると後々、大規模なデータ移行やインデックス再構築という「大手術」が必要になります。
まずは自分の管理しているDBで、`pg_stat_user_tables` を覗いてみてください。「あ、このテーブル、結構ゴミが溜まってるな」と気づくことが、チューニングの第一歩です。
何か困ったことや、特定のテーブルでバキュームが刺さる現象があれば、またいつでも相談してくださいね。現場からは以上です!
コメント