私はSQL Server、Oracle、Sybase DBAの出身ですが、現在PostgreSQL 9.6.12を実行しているAWS Auroraクラスターを調べています。質問。どこを見ても答えは見つかりません。デフォルトのautovacuumおよびautoanalyze値は引き続き設定されています。 Autovacuumdoesは、最終的にアプリケーションテーブルで実行する必要があることを実行しているように見えますが、私が気付いたことは、そのときは、システムテーブルの小さなセットを頻繁に掃除して分析します。彼らです:
これは、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アクティビティの半分が自動バキュームプロセスによって消費されていることを示しています:
最初は、多くの一時テーブルが作成されてから破棄されたためか、タプルの数がたとえば約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|
要約すると、私が求めていることは、少数のシステムテーブルのセットが常に一貫して自動バキューム処理されることは正常ですか?どんな洞察もいただければ幸いです。
SQLクエリの出力を投稿して、自動バキュームの頻度を正確に指定できますか?これらの5つのシステムカタログテーブルの行数はいくつですか?多くのDDLステートメントが頻繁に実行されていますか?
最後のVACUUM以降に廃止されたタプルの数が次のように定義されたバキュームしきい値を超えると、自動バキュームが実行されます。
vacuum threshold = autovacuum_vacuum_threshold + autovacuum_vacuum_scale_factor *pg_class.reltuples;
あなたの場合:50 + 0.1 * pg_class.reltuples
常にバキューム処理されていると言及しているカタログテーブルは、実際にテーブル(または、可能性は低いですが、複合データ型)が常に作成および破棄されていることを示しています。
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