【実務・中級編】 オートバキュームワーカー – PostgreSQL

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` を覗いてみてください。「あ、このテーブル、結構ゴミが溜まってるな」と気づくことが、チューニングの第一歩です。

何か困ったことや、特定のテーブルでバキュームが刺さる現象があれば、またいつでも相談してくださいね。現場からは以上です!

コメント

タイトルとURLをコピーしました