14.7 TB Postgres(9.1)データベースがあり、長時間の大量の書き込みに耐える必要があります。dbロックアップを防ぐために、トランザクションIDを厳密に管理する必要があることを知っています。最近、クエリが遅くなり、大規模な読み取り専用テーブルで複数の自動バキュームが実行されており、「(ラップアラウンドを防止するため)」という添え字が付いていることがわかりました。実行中のソフトウェアを停止して_vacuumdb -F -a
_コマンドを実行しました。実行_select current_query from pg_stat_activity
_手動バキューム中でも自動バキュームプロセスが実行されていることがわかります。自動バキュームをselect pg_cancel_backend(pid)
で強制終了すると、自動バキュームが停止しましたが、すぐに再起動しました。私の質問:
自動バキュームはテーブルのテーブル統計によってトリガーされ、手動のVACUUM (FREEZE)
が実行されない限り、これらは更新されません。そのため、回り込み防止の自動バキュームプロセスが引き続き開始されます。
しかし、それは大きな問題ではありません。テーブルで実行できるVACUUM
は一度に1つだけです。これで、回り込み防止の自動バキュームワーカーは、別のプロセスをブロックするときにあきらめなくなります。その場合は、マニュアルVACUUM
です。ただし、ラップアラウンド防止自動バキュームワーカーを強制終了すると、手動でVACUUM
がロックを取得し、再起動されたラップアラウンド防止自動バキュームワーカーがブロックされます。 pg_locks
を見て、ロックを待機していることを確認します(granted = FALSE
)。
これでvacuumdb
は1つのテーブルを順番に処理するため、次のテーブルの処理を開始し、そこで新しい自動バキュームワーカーによってブロックされるとすぐに、自動バキュームワーカーを強制終了する準備ができている必要があります。
VACUUM
を使用するよりも、大きな読み取り専用テーブルでvacuumdb
を手動で起動する方が簡単な場合があります。これは、どのテーブルがバキュームされるかを制御できるためです。
VACUUM
を高速化するには、必ずmaintenance_work_mem
を高く設定してください。また、少なくともこれらの大きなテーブルでは、autovacuum_vacuum_cost_delay
を2ms以下に設定して、将来の自動バキュームの実行が速くなるようにする必要があります。
将来の痛みを軽減するには、影響を受けるテーブルのautovacuum_freeze_max_age
を大幅に下げます。次に、次のラップアラウンド防止バキュームがより早く開始され、より速く実行されます。
何よりも、できるだけ早くv13にアップグレードしてください。そのバージョンから、挿入のみのテーブルで定期的にバキュームが実行され、問題が解消されるためです。