はじめに
DB初心者が、業務中やプライベートでDBをいじっている時に困ったことをメモとして残します
環境情報
PostgreSQL 16.4 (Homebrew) on x86_64-apple-darwin23.4.0
何があったのか
-
やりたかったこと
以下テーブルのレコードを100件ほど追加して、auto vacuumでテーブルの統計情報が更新されることを確認したかった。売上id 売上合計 映画タイトル 売上日 1 12000 映画タイトル1 2024-01-01 2 15000 映画タイトル2 2024-01-01 3 11000 映画タイトル3 2024-01-02 4 13000 映画タイトル1 2024-01-02 5 16000 映画タイトル5 2024-01-03
- 起こったこと
レコードを100件インサートした後に以下クエリを実行
select relname,last_autoanalyze from pg_stat_user_tables where relname = 'eiga'
結果、last_autoanalyzeはnullになっており、auto vacuumは実行されていなかった
auto vacuumの仕組み
auto vacuumは以下3つのプロセスが関係しており、図で書くとこんな感じ?
1. postmaster
2,3のプロセスを開始する
2. auto vacuum ランチャー
vacuumを実行するための情報を収集し、ポストマスターに伝える。
※ pg_stat_user_tables等のシステムビューを参照している。
自動バキュームランチャープロセスは、テーブルでバキューム操作を実行するための自動バキュームワーカープロセスを開始する適切なタイミングを決定します。
auto vacuumが必要かどうかの判断については、以下の設定値が用いられる
- autovacuum_vacuum_threshold:50(デフォルト)
- 50行更新されたら、auto vacuumが走る
- analyze_scale_factor:0.1
- テーブルのレコード数の10%を超えた更新が入ったら、auto vacuumが走る
- autovacuum_analyze_threshold:
- 50行更新されたら、auto vacuumが走る(analyze)
- autovacuum_vacuum_insert_threshold:
- 1000行挿入されたら、auto vacuumが走る(analyze)
- autovacuum_vacuum_insert_scale_factor:
- テーブルの20%行挿入されたら、auto vacuumが走る(analyze)
3. auto vacuum ワーカー
実際にvacuumを実行するプロセス
テーブルに対してバキューム操作を実行する実際のワーカープロセスです。ランチャーによってスケジュールされたとおりにデータベースに接続し、カタログテーブルを読み取り、バキューム操作を実行するためのテーブルを選択します。
どう解決したのか
私が勘違いしていたこととして、
autovacuum_analyze_thresholdが50ということを確認したので、
「50レコードinsertすれば、auto vacuumが走ってanalzeしてくれる!」と思ってました。
実態は、先ほどのauto vacuumの設定値で記載したとおり、大きく2つの判断基準があります
- autovacuum_analyze_threshold:50(デフォルト)
- 50行更新されたら、auto vacuumが走る(analyze)- autovacuum_vacuum_insert_threshold:1000(デフォルト)
- 1000行挿入されたら、auto vacuumが走る(analyze)
この「autovacuum_analyze_threshold」はupdate,deleteのことを指しており
この「autovacuum_vacuum_insert_threshold」はinsertのことを指しているとのこと
つまり、insertをする場合は50件ではなく、1,000件必要だったということです。
実際に以下の2パターンでauto_vacuum(analyze)が発生するかを検証してみましたが、
いずれもauto_vacuum(analyze)はちゃんと動いてくれました。
- 1000件のinsert
- 50件のdelete
おわりに
すごく初歩的で誰も躓かないようなところだったかもしれませんが、誰かの役たてば嬉しいです