web-dev-qa-db-ja.com

PostgreSQL 9.6.12 autovacuumがシステムテーブルで常に実行されています

私はSQL Server、Oracle、Sybase DBAの出身ですが、現在PostgreSQL 9.6.12を実行しているAWS Auroraクラスターを調べています。質問。どこを見ても答えは見つかりません。デフォルトのautovacuumおよびautoanalyze値は引き続き設定されています。 Autovacuumdoesは、最終的にアプリケーションテーブルで実行する必要があることを実行しているように見えますが、私が気付いたことは、そのときは、システムテーブルの小さなセットを頻繁に掃除して分析します。彼らです:

  1. pg_type
  2. pg_shdepend
  3. pg_attribute
  4. pg_class
  5. pg_depend

これは、AWS Performance Insightsデータと、このコードを使用したデータベースインスタンスへの直接クエリの両方で確認できます。

    WITH rel_set AS
(
    SELECT
        oid,
        CASE split_part(split_part(array_to_string(reloptions, ','), 'autovacuum_analyze_threshold=', 2), ',', 1)
            WHEN '' THEN NULL
        ELSE split_part(split_part(array_to_string(reloptions, ','), 'autovacuum_analyze_threshold=', 2), ',', 1)::BIGINT
        END AS rel_av_anal_threshold,        
        CASE split_part(split_part(array_to_string(reloptions, ','), 'autovacuum_vacuum_threshold=', 2), ',', 1)
            WHEN '' THEN NULL
        ELSE split_part(split_part(array_to_string(reloptions, ','), 'autovacuum_vacuum_threshold=', 2), ',', 1)::BIGINT
        END AS rel_av_vac_threshold,
        CASE split_part(split_part(array_to_string(reloptions, ','), 'autovacuum_analyze_scale_factor=', 2), ',', 1)
            WHEN '' THEN NULL
        ELSE split_part(split_part(array_to_string(reloptions, ','), 'autovacuum_analyze_scale_factor=', 2), ',', 1)::NUMERIC
        END AS rel_av_anal_scale_factor,        
        CASE split_part(split_part(array_to_string(reloptions, ','), 'autovacuum_vacuum_scale_factor=', 2), ',', 1)
            WHEN '' THEN NULL
        ELSE split_part(split_part(array_to_string(reloptions, ','), 'autovacuum_vacuum_scale_factor=', 2), ',', 1)::NUMERIC
        END AS rel_av_vac_scale_factor
    FROM pg_class
) 
SELECT
    PSUT.relname,
--    to_char(PSUT.last_analyze, 'YYYY-MM-DD HH24:MI')     AS last_analyze,
    to_char(PSUT.last_autoanalyze, 'YYYY-MM-DD HH24:MI') AS last_autoanalyze,    
--    to_char(PSUT.last_vacuum, 'YYYY-MM-DD HH24:MI')     AS last_vacuum,
    to_char(PSUT.last_autovacuum, 'YYYY-MM-DD HH24:MI') AS last_autovacuum,
    to_char(C.reltuples, '9G999G999G999')               AS n_tup,
    to_char(PSUT.n_dead_tup, '9G999G999G999')           AS dead_tup,
    to_char(coalesce(RS.rel_av_anal_threshold, current_setting('autovacuum_analyze_threshold')::BIGINT) + coalesce(RS.rel_av_anal_scale_factor, current_setting('autovacuum_analyze_scale_factor')::NUMERIC) * C.reltuples, '9G999G999G999') AS av_analyze_threshold,
    to_char(coalesce(RS.rel_av_vac_threshold, current_setting('autovacuum_vacuum_threshold')::BIGINT) + coalesce(RS.rel_av_vac_scale_factor, current_setting('autovacuum_vacuum_scale_factor')::NUMERIC) * C.reltuples, '9G999G999G999') AS av_vacuum_threshold,
    CASE
        WHEN (coalesce(RS.rel_av_anal_threshold, current_setting('autovacuum_analyze_threshold')::BIGINT) + coalesce(RS.rel_av_anal_scale_factor, current_setting('autovacuum_analyze_scale_factor')::NUMERIC) * C.reltuples) < PSUT.n_dead_tup
        THEN '*'
    ELSE ''
    end
    AS expect_av_analyze,    
    CASE
        WHEN (coalesce(RS.rel_av_vac_threshold, current_setting('autovacuum_vacuum_threshold')::BIGINT) + coalesce(RS.rel_av_vac_scale_factor, current_setting('autovacuum_vacuum_scale_factor')::NUMERIC) * C.reltuples) < PSUT.n_dead_tup
        THEN '*'
    ELSE ''
    end
    AS expect_av_vacuum,
    PSUT.autoanalyze_count,
    PSUT.autovacuum_count
FROM
    pg_stat_all_tables PSUT
    JOIN pg_class C
        ON PSUT.relid = C.oid
    JOIN rel_set RS
        ON PSUT.relid = RS.oid
ORDER BY PSUT.autoanalyze_count DESC; --C.reltuples

AWS RDS Performance Insightsのグラフは、CPUアクティビティの半分が自動バキュームプロセスによって消費されていることを示しています: RDS Performance Insights screen grab

最初は、多くの一時テーブルが作成されてから破棄されたためか、タプルの数がたとえば約8,000から8,000,000に定期的に移動し、その後いくつかの前述の表。しかし、一時テーブルが作成された証拠を見つけることができず、オフショア開発者はそれらを使用しないと言っています。

この種の動作は、通常のPostgreSQLまたはAurora(PostgreSQL)では正常ですか?これが正常でない場合、ここで何が起こっているのかを確認するために誰かが見ることを提案できるでしょうか? RAM(shared_buffersに割り当てられた75%-Auroraのデフォルト)の122GBのインスタンスでは、このデータベースのサイズは約テラバイトです。

Autovaccum設定fromを変更して、このデータベースを処理するためのデフォルトを大幅に増やしますが、それが無駄にならないようにしたいだけです問題のテーブルがautovacuum/autoanalyseの時間を独占している場合の時間。

現在の設定(pg_settingsから):

autovacuum  on
autovacuum_analyze_scale_factor 0.05
autovacuum_analyze_threshold    50
autovacuum_freeze_max_age   200000000
autovacuum_max_workers  3
autovacuum_multixact_freeze_max_age 400000000
autovacuum_naptime  5
autovacuum_vacuum_cost_delay    5
autovacuum_vacuum_cost_limit    -1
autovacuum_vacuum_scale_factor  0.1
autovacuum_vacuum_threshold 50

クエリの関連出力は次のとおりです。 autoanalyze_countおよびautovacuum_countの列に注意してください。このインスタンスは6日間しか実行されていないため、これらの数値は信じられないほど高くなっています。他のすべてのテーブルでは、それらの列について0〜10しか表示されません(残りのテーブルは効率化のために入れていません)。

relname                                             |last_autoanalyze|last_autovacuum |n_tup         |dead_tup      |av_analyze_threshold|av_vacuum_threshold|expect_av_analyze|expect_av_vacuum|autoanalyze_count|autovacuum_count|
----------------------------------------------------|----------------|----------------|--------------|--------------|--------------------|-------------------|-----------------|----------------|-----------------|----------------|
pg_type                                             |2020-03-06 18:20|2020-03-06 18:20|         1,352|           192|           118      |           185     |*                |*               |            22781|           34428|
pg_shdepend                                         |2020-03-06 18:20|2020-03-06 18:20|       694,312|           164|        34,766      |        69,481     |                 |                |            20945|           73784|
pg_class                                            |2020-03-06 18:20|2020-03-06 18:20|         1,172|           264|           109      |           167     |*                |*               |            13758|           21198|
pg_attribute                                        |2020-03-06 18:20|2020-03-06 18:20|         9,205|         1,976|           510      |           970     |*                |*               |            12692|           17710|
pg_depend                                           |2020-03-06 18:20|2020-03-06 18:20|        10,981|         1,143|           599      |         1,148     |*                |                |            11255|           16883|

要約すると、私が求めていることは、少数のシステムテーブルのセットが常に一貫して自動バキューム処理されることは正常ですか?どんな洞察もいただければ幸いです。

2
dodgybugga

SQLクエリの出力を投稿して、自動バキュームの頻度を正確に指定できますか?これらの5つのシステムカタログテーブルの行数はいくつですか?多くのDDLステートメントが頻繁に実行されていますか?

最後のVACUUM以降に廃止されたタプルの数が次のように定義されたバキュームしきい値を超えると、自動バキュームが実行されます。

vacuum threshold =  autovacuum_vacuum_threshold +  autovacuum_vacuum_scale_factor *pg_class.reltuples;

あなたの場合:50 + 0.1 * pg_class.reltuples

1
pifor

常にバキューム処理されていると言及しているカタログテーブルは、実際にテーブル(または、可能性は低いですが、複合データ型)が常に作成および破棄されていることを示しています。

  • pg_classはテーブル(およびその他の関係)のテーブルです
  • pg_attributesは列のテーブルです
  • pg_typeにはタイプが含まれ、すべてのテーブルに対して同じ名前の複合タイプが作成されます
  • pg_dependには、テーブルと、たとえば関連するタイプとの間の依存関係が含まれています。
  • pg_shdependには、テーブルと所有ロールの間の依存関係が含まれています。

膨張のリスクが最も高いテーブルはpg_attribute

ホストされたデータベースを使用しているため、おそらくスーパーユーザーアクセス権も、テーブルの肥大度を正確に判断できるpgstattuple拡張機能も使用できません。

しかし、あなたはそのサイズを知ることができます:

SELECT pg_total_relation_size('pg_attribute');

また、死んだ(削除された)タプルの数を調べることもできます。

SELECT n_live_tup, n_dead_tup
FROM pg_stat_sys_tables
WHERE relname = 'pg_attribute';

あなたが見る死んだタプルは、列が削除された証拠です。したがって、この数が増え続ける場合は、開発者が誤っているという証拠があります(おそらく一時テーブルではなく、通常のテーブルです)。

問題を回避するために、できる限りautovacuumを積極的にします。

autovacuum_vacuum_cost_delay = 0
0
Laurenz Albe