Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Report oldest xmin source when autovacuum canno...

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on. →
Avatar for Shinya Kato Shinya Kato
September 16, 2026

Report oldest xmin source when autovacuum cannot remove tuples (Japan PostgreSQL Developer Meetup - PAIKAJI) 日本語版

2026年9月18日
加藤 慎也

Avatar for Shinya Kato

Shinya Kato

September 16, 2026

More Decks by Shinya Kato

Other Decks in Technology

Transcript

  1. Report oldest xmin source when autovacuum cannot remove tuples Shinya

    Kato Japan PostgreSQL Developer Meetup · September 18, 2026
  2. 03 Vacuum の処理の流れ Vacuum 開始 oldest xmin 計算 ① Scanning

    heap 1 Vacuuming indexes Vacuuming heap ② Cleaning up indexes Truncating heap ログ出力 ③ oldest xmin を計算する ProcArray を走査し、全バックエンドの xid / xmin から最小値を求める レプリケーションスロットの xmin は、集約済みの値を ProcArray から読む 最小値だけが残り、その値になった理由は残らない その oldest xmin でデッドタプルを回収する 3 結果をログに出力する 2
  3. Vacuum のログは oldest xmin の理由を出力しない 回収されなかったデッドタプル数と、削除可否に使用する oldest xmin のみが出力される。 =#

    VACUUM (VERBOSE) t; tuples: 0 removed, 20000 remain, 10000 are dead but not yet removable removable cutoff: 696, which was 2 XIDs old when operation ended DBA は、この 696 という値から根本原因を探る必要がある。 04
  4. デッドタプルを回収できない原因は 4 種類ある 原因 確認するビュー ロングトランザクション pg_stat_activity.backend_xid pg_stat_activity.backend_xmin 未コミットの準備済みトランザクション hot_standby_feedback

    有効時の スタンバイでの参照クエリ 論理レプリケーションの遅延 pg_prepared_xacts pg_stat_replication.backend_xmin (スロットを使用していない場合) pg_replication_slots.xmin (スロットを使用している場合) pg_replication_slots.catalog_xmin 原因ごとにそれぞれ違うビューを確認する必要がある。さらに、これらのビューは現在の状態しか持た ないため、原因が解消した後では事後解析ができない。そこで、oldest xmin の理由を Vacuum のログ に出力したい。 05
  5. 06 当初の提案 Vacuum 開始 oldest xmin 計算 次の条件を満たす場合のみ、ProcArray と Replication

    slot を再走査して出力する Scanning heap VACUUM (VERBOSE)、または autovacuum の実行時間が log_autovacuum_min_duration を超えた 回収できなかったデッドタプルがある Vacuuming indexes Vacuuming heap tuples: 0 removed, 20000 remain, 10000 are dead but not yet removable oldest xmin blocker: idle in transaction (pid = 12345) removable cutoff: 696, which was 2 XIDs old when operation ended Cleaning up indexes Truncating heap ログ出力 再走査
  6. 当初の提案の課題 Vacuum 開始時に計算した oldest xmin で再走査するので、oldest xmin 計算後に原因が 解消している場合には、ログ出力時に報告できない。 例:

    Vacuum 開始時には存在したロングトランザクションが、Vacuum 終了時には完了していた tuples: 1 removed, 200000 remain, 100000 are dead but not yet removable removable cutoff: 1026, which was 35981 XIDs old when operation ended (oldest xmin blocker の行が出力されない) 07
  7. 08 対案 oldest xmin を計算するときに調べておけばよいのでは、という複数のレビュアーからのコメントを 受けた案。 Vacuum 開始 oldest xmin

    計算 ① 計算中に保存 Scanning heap Vacuuming indexes Vacuuming heap Cleaning up indexes 再走査が不要になる。 Truncating heap ログ出力 oldest xmin 計算時に、候補の xid と xmin を 別々に保存しておく 2 ログ出力時は走査せず、① で保存した情報をそ のまま出力する 1 ② 出力のみ
  8. 対案の課題 09 誤った情報が報告される oldest xmin 計算時のロングトランザクションのセッションが切れていても、その当時の pid が報告される 存在していたレプリケーションスロットが削除済みでも、その名前が報告される procArray->replication_slot_xmin

    からは、standby が接続中なのか standby 不在でスロ ットが残存しているのかが区別できない 区別するにはレプリケーションスロットの再走査が必要 oldest xmin 計算時 (ProcArrayLock 取得中) には、対象のトランザクションが active か idle かを判断できない oldest xmin 計算時 (ProcArrayLock 取得中) には、レプリケーションスロット名を引けない (ReplicationSlotControlLock が必要)
  9. 10 統合案 Vacuum 開始 oldest xmin 計算 ① 計算後に走査 Scanning

    heap Vacuuming indexes Vacuuming heap Cleaning up indexes Truncating heap ログ出力 ② 再走査 oldest xmin 計算後に走査し、原因を特定して 保存しておく ログ出力時にもう一度走査し、原因がまだ存在 2 していればそれを出力する。存在しなければ ① の保存分を使う 1 ① の保存分を使う場合は at cutoff time の注釈を付け ることで、古い情報だと分かるようにする。
  10. 統合案の出力 候補が見つかった場合 tuples: 0 removed, 20000 remain, 10000 are dead

    but not yet removable oldest xmin blocker: idle in transaction (pid = 12345) removable cutoff: 696, which was 2 XIDs old when operation ended 候補が存在していない場合 tuples: 1 removed, 200000 remain, 100000 are dead but not yet removable oldest xmin blocker at cutoff time: idle in transaction (pid = 12345) removable cutoff: 1026, which was 35981 XIDs old when operation ended 11
  11. 今後の検討 — 要約版 同じ xid / xmin で oldest xmin

    の候補になっているものをすべて保持し、要約を出力する案。 tuples: 0 removed, 20000 remain, 10000 are dead but not yet removable oldest xmin blocker: idle in transaction (pid = 12345) logical replication slot "sub_slot" also holds this xmin 11 other processes hold snapshots at this xmin removable cutoff: 696, which was 2 XIDs old when operation ended 候補はすでに全件収集しているため、走査は増えない 1 件だけ解消しても cutoff が動かない、という事態を避けられる diagnostic log の先例に沿う (log_lock_waits など) Scott Ray からの提案 · 2026-08-08 12