web-dev-qa-db-ja.com

Postgresスロークエリ-自動バキューム頻度

ここ数週間でプラットフォームのパフォーマンスが低下していることに気付いたので、以下を実行しました。

select relname, last_vacuum, last_autovacuum, last_analyze, last_autoanalyze 
from pg_stat_user_tables 
where relname like 'core_%';

また、プライマリテーブルが1週間以上自動バキュームされていないことに注意してください。だから先週私は走った:

vacuum analyse verbose TABLENAME

これで問題は解決したようですが、同じ問題が再び発生しました。よく調べてみると、多くのテーブルは分析されておらず(自動またはその他)、マニュアル以外はvacuum analyse先週実行しました。手動でバキューム処理されたテーブルはなく、他の多くのテーブルは、せいぜい数日前から、さらに悪い場合は数週間前に自動バキュームされていません。

用語の私の理解は次のとおりです。

  • バキューム:削除されたレコードをディスクから消去します
  • 分析:クエリプランナーを更新します

postgres.conf、autovacuumプロパティはコメントアウトされていますが、ドキュメントにはデフォルトでオンになっていると記載されているため、コメント化されていてもオンになっているはずです。

テーブルが頻繁にバキュームされて分析されない理由を誰かが説明できますか?より具体的には、これらの値が実際に更新されないのは、システムにそれほど大きな影響があるのでしょうか?

情報:Postgres 9.1 OS:Ubuntu 12.04

の出力

SELECT relname as "Table",
pg_size_pretty(pg_total_relation_size(relid)) As "Size",
pg_size_pretty(pg_total_relation_size(relid) - pg_relation_size(relid)) as "External Size"
FROM pg_catalog.pg_statio_user_tables 
ORDER BY pg_total_relation_size(relid) DESC;


     Table       | Size | External Size
-----------------+------+---------------
"Primary Table"  | 27G  |     8232M
4
justcompile

バキューム:削除されたレコードをディスクから消去します

ではない正確に。 VACUUMは、アクティブなトランザクションから見えなくなった行をデッドとしてマークします(再利用の準備ができています)。物理的な最後で完全にデッド/空のページを除いて、テーブルを表す物理ファイルのサイズは縮小されません。 マニュアルはすべてを説明しています おそらく、ここで要約するよりも優れています。

分析:クエリプランナーを更新します

正式にはANALYZEで、Zが付いていますが、ANALYSEも代替スペルとして受け入れられます。また、クエリプランナーが使用する統計usedを更新します。繰り返しますが、 マニュアルにはすでに最良の説明が記載されています

postgres.conf ...では、コメント化されていてもオンのままになっていると思いますか?

そのとおりです。繰り返しますが、 マニュアルの詳細 を検討してください。

その多くの書き込み操作(1分間に数千レコード)により、システムは通常のVACUUM/ANALYZE実行します。これでマニュアルを読んだので、結果を理解しました。あなたのテーブルなら...

1週間以上自動バキュームが行われていませんでした。

...次に、いくつかの理由からbadです。また、 @ Daniel's answer を検討してください。これは、あなたのような巨大なテーブルでどのように発生したのでしょうか。または、高負荷のためにテーブルが常にロックされ、VACUUMに処理を行わせないことができます。繰り返しますが、それはすべて マニュアルに記載されています です。これは、設定を調整する方法についての適切な回答を示した関連ケースです。

per-table settings(STORAGE parameters) を使用して、特別なテーブルの特別なニーズに合わせて微調整し、システムの残りの部分はそのままにしておくことができます。

If最近挿入された行を更新する場合、100未満のFILLFACTORは非常に役立ちます。 CLUSTERまたはpg_repackを使用してテーブルを(一度)圧縮してから、FILLFACTORを100未満に設定できます。また、巨大なテーブルの場合は、より高く設定することもできます STATISTICS 不規則なデータ分布を持つキー列のターゲット。

また、古い行がめったに更新されない場合、パーティション化は古いセクションを別の方法で処理するための良い解決策になるかもしれません。それは本当に全体像に依存します...

また、インデックスも忘れないでください。これらも肥大化する可能性があります。実際に必要なインデックスのみを保持してください。

死んだタプルと生きたタプルの数を表示するには:

8

おそらくあなたのケースを説明する式は次のとおりです( The Autovacuum Daemon に記載されています):

...最後のVACUUM以降に廃止されたタプルの数が "vacuum threshold"を超える場合、テーブルはバキュームされます。真空しきい値は次のように定義されます

vacuum threshold = vacuum base threshold + vacuum scale factor * number of tuples

ここで、バキュームベースのしきい値はautovacuum_vacuum_threshold、バキュームスケール係数はautovacuum_vacuum_scale_factor、タプルの数はpg_class.reltuplesです。

新しいタプルを一定の速度でINSERT/UPDATしている場合、タプルの総数に対する死んだタプルの比率(pg_class.reltuples)は、タプルの総数が増え続けるにつれて、ますます小さくなっています。バキュームがその仕事をするので、死んだタプルの数は減り、管理されますが、タプルの総数ではありません。

したがって、時間の経過とともに、バキュームのしきい値に到達する頻度が低くなり、autovacuumが実際に大きなテーブルを処理しないように見えます。このテーブルのしきい値を下げてその頻度を上げることができますが、必要な追加のI/O帯域幅に注意してください。

高速で永久に成長するテーブルは持続可能ではありません。そのため、管理可能な量のライブデータを、autovacuumで安全に無視できるはるかに大量の読み取り専用データから分割して分離する設計変更を考えることができます。

3
Daniel Vérité