PostgreSQLの「縁の下の力持ち」、Autovacuum Launcherと上手く付き合う方法
「最近、DBの反応がなんだか重い……」
「古いデータの削除はしたはずなのに、なぜかストレージが減らない……」
PostgreSQLを触っていると、一度はこんな悩みにぶつかりますよね。そんな時、多くのエンジニアが真っ先に疑うのが、そう、「Autovacuum(自動バキューム)」です。
今日は、その司令塔である「Autovacuum Launcher」というプロセスに焦点を当てて、現場で役立つ知識をシェアしたいと思います。教科書的な説明は公式ドキュメントに任せるとして、ここでは「なぜあいつは時々サボるのか?」「どうやって手なずければいいのか?」という、実務的な話をしましょう。
—
Autovacuum Launcherの「仕事」は何か?
まず、勘違いしやすいポイントを一つ。「Autovacuum Launcher」自身は、直接データに触れてゴミ掃除をするわけではありません。
彼(彼女)の役割は、あくまで「現場監督」です。
バックグラウンドで常に目を光らせていて、統計情報を元に「お、このテーブルはデッドタプル(削除されたデータの残骸)が溜まりすぎてるな。そろそろ掃除が必要だ!」と判断したら、部下である「Autovacuum Worker」プロセスをフォーク(起動)させて、掃除を命じる。これがLauncherの全貌です。
なぜ「Launcher」がボトルネックになるのか?
たまに、「Autovacuumが全然動いてくれない!」という相談を受けますが、多くの場合、原因はLauncherの仕組みにあります。
- チェック頻度の限界: Launcherは `autovacuum_naptime` という設定値ごとにテーブルをスキャンしに行きます。デフォルトは1分ですが、テーブル数が数万個あるような大規模データベースだと、スキャンが追いつかず、掃除の開始が遅れることがあります。
- ワーカー数の制限: 掃除を担当するWorkerは、同時に走れる数が決まっています(`autovacuum_max_workers`)。重いテーブルが数個あると、他の小さいテーブルが順番待ちになってしまう。これが「掃除が追いつかない」の正体です。
—
現場で役立つ「監視とチューニング」の実践知
理論はこれくらいにして、実際に僕が現場でよく使うチェック方法を紹介します。
1. 「本当に掃除が追いついているか」を確認する
まず、今のテーブルがどれくらい汚れているかを見てみましょう。以下のクエリを叩いてみてください。
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` が異常に高いのに、`last_autovacuum` が古いままなら、Autovacuumがサボっている証拠です。
2. テーブルごとに「お仕置き」をする
もし、「このテーブルだけは頻繁に更新されるから、もっと厳しく掃除してほしい!」という場合は、グローバルな設定をいじるよりも、テーブル単位で設定を変えるのがプロのやり方です。
— 特定のテーブルだけ、掃除の閾値を低く設定する
ALTER TABLE my_important_table SET (
autovacuum_vacuum_scale_factor = 0.01, — 1%の更新で掃除開始(デフォルトは20%)
autovacuum_vacuum_threshold = 1000 — 1000行更新されたら掃除
);
こうすることで、他のテーブルには影響を与えずに、特定のテーブルだけ「こまめに掃除する」という調整が可能です。
—
先輩からのアドバイス:Autovacuumを恐れるな
たまに「AutovacuumがディスクI/Oを圧迫するからOFFにしたい」という強者がいますが、絶対にやめてください。
PostgreSQLにおいて、バキュームは「心臓の鼓動」と同じです。止まればデータは肥大化し、インデックスは劣化し、クエリは遅くなり、最後にはトランザクションIDの周回問題でDBが停止します。
もしI/Oが気になるなら、以下のパラメータを調整して「優しく掃除させる」のが正解です。
- `autovacuum_vacuum_cost_limit`: 一度にどれだけ仕事をしていいかの限界値。これを上げると掃除が早くなる。
- `autovacuum_vacuum_cost_delay`: 掃除の合間に入れる休憩時間。これを上げるとI/O負荷が下がる。
—
まとめ
Autovacuum Launcherは、決して気まぐれで動いているわけではありません。統計情報という「データ」に基づいて、必死にDBの健康を保とうとしている健気な奴なんです。
もしDBの調子が悪いときは、ログを眺めて「Launcherは今、何が忙しいのか?」を想像してみてください。ログレベルを上げて `log_autovacuum_min_duration` を設定しておくと、どこで掃除が詰まっているかが一目瞭然になります。
「掃除はプロに任せて、自分はクエリの設計に集中する」。これが、PostgreSQLを使いこなすエンジニアの理想形です。
それでは、良いデータベースライフを!
コメント