web-dev-qa-db-ja.com

PostgreSQL ANALYZEの実行時間は24時間を超えます(まだ実行中)

Pg_upgradeを使用してPostgres DB 9.3.2-> 10.5をアップグレードしました(その場で)。ドキュメントとpg_upgradeの指示に従ってすべてを行いました。すべてがうまくいきましたが、インデックスがテーブルの1つで使用されていないことに気付きました(おそらく他のテーブルも影響を受けています)。

それで、私は昨日そのテーブルでANALYZEを開始しました(22時間以上)まだ実行中です...

質問:ANALYZEが非常に長い実行時間を持つことは正常ですか?

テーブルには約30Mのレコードが含まれています。構造は次のとおりです。

CREATE TABLE public.chs_contact_history_events (
    event_id bigint NOT NULL
           DEFAULT nextval('chs_contact_history_events_event_id_seq'::regclass),
    chs_id integer NOT NULL,
    event_timestamp bigint NOT NULL,
    party_id integer NOT NULL,
    event integer NOT NULL,
    cause integer NOT NULL,
    text text COLLATE pg_catalog."default",
    timestamp_offset integer,
    CONSTRAINT pk_contact_history_events PRIMARY KEY (event_id)
);

ALTER TABLE public.chs_contact_history_events OWNER to c_chs;

CREATE INDEX ix_chs_contact_history_events_chsid
    ON public.chs_contact_history_events USING hash (chs_id)
    TABLESPACE pg_default;

CREATE INDEX ix_chs_contact_history_events_id
    ON public.chs_contact_history_events USING btree (event_id)
    TABLESPACE pg_default;

CREATE INDEX ix_history_events_partyid
    ON public.chs_contact_history_events USING hash (party_id)
    TABLESPACE pg_default;

UPDATE:

現在実行中のプロセスを取得するために以下のクエリを実行し、興味深い結果を得ました。

SELECT pid, now() - pg_stat_activity.query_start AS duration, query, state
FROM pg_stat_activity
WHERE (now() - pg_stat_activity.query_start) > interval '5 minutes'
AND state = 'active';

abnormal running queries on that table

インデックステーブルのメンテナンスタスクと同時再作成がフリーズしているようです!

次の質問:これらのプロセスをキャンセルしても安全ですか?そして次に何をすべきか?それらをすべて停止し、インデックス作成を再開するIMOが必要になりますが、よくわかりません。


ANNEX 1

おそらく関連するエラーがv9で修正されました:

9.3.7および9.4.2他のプロセスがインデックスを同時に変更している場合に、ハッシュインデックスバケットの分割中に発生する可能性がある障害を修正します。

9.3.18および9.4.13および9.5.8および9.6.4 Windowsビルドでの共有述語ロックハッシュテーブルの低確率破損を修正

9.5.4大きな(shared_buffersより大きい)ハッシュインデックスの構築の修正大きなインデックスに使用されるコードパスには、不正なハッシュ値がインデックスに挿入されるバグが含まれていたため、後続のインデックス検索は、インデックスに挿入されたタプルを除いて常に失敗しました最初のビルドの後。

おそらく関連するエラーがv10で修正されました:

10.2新しいオーバーフローページを追加した後、ハッシュインデックスのメタページをダーティとしてマークできず、インデックスが破損する可能性があるのを修正

単純なハッシュテーブルの過度の増加によるメモリ不足の障害を防止する


そして最後に、それは私を心配させます(アップグレードは生産的な環境では現実的ではないようですので):

10.6 BLCKSZがデフォルトよりも小さい場合、ハッシュインデックスのメタページのオーバーランを回避する

ハッシュインデックスの失われたページのチェックサム更新を修正する


ANNEX 2

V10でのアップグレード手順:

以前のメジャーPostgreSQLバージョンからのpg_upgrade-ingの後にハッシュインデックスを再構築する必要があります

ハッシュインデックスの大幅な改善により、この要件が必要になりました。 pg_upgradeはこれを支援するスクリプトを作成します。

もちろん、このスクリプトはアップグレード時に実行しました。

7
wjozsi

数時間の調査と現在の状況の調査の後、私は問題を解決することができたと思います。 (多くのユーザーypercubeにインスピレーションを与えてくれたことと、同じ解決策を同時に実現したErwin Brandstetterに感謝します。)

したがって、問題にはいくつかの層がありました。

1。)アップグレード

Pg_upgrade 9.3.2からのアップグレード-> 10.5は2つのステップで行う必要があります。最初に同じ行内(9.3.2-> 9.3.25)に、次に10.x(私の場合は10.5)に

直接アップグレードしたところ、問題の根本的な原因だったようです。

2。)ハッシュインデックス

ハッシュインデックスは、既に修正されているpostgresのいくつかの奇妙なエラーに悩まされているようですが、修正前のバージョンのインデックスを使用するとエラーが発生します

。)冷凍タスク

非現実的な長時間実行されているpostgresプロセスを探すことは理にかなっています。 (質問のクエリを参照してください。)私の場合、インデックスの再作成がどういうわけかスタックし、他のいくつかのタスクもブロックされていることがわかりました。

SELECT pg_cancel_backend(__pid__);を使用してそれらのほとんどをキャンセルしても安全です。ここでpidは、前述のクエリの結果セットで見つかったプロセスIDです。だから私はそれをやった。自動バキュームプロセスも停止しました。

4。)メモリ操作

結局のところ、次の問題に直面して、新しいインデックスを削除して作成できると思いました。約1分後、すべてのメンテナンスクエリがエラーメッセージで終了しました。

ERROR: out of memory
DETAIL: Failed on request of size 22355968.
SQL state: 53200

メモリ処理が9.3と10の間で変更されたようです。構成内のmaintenance_memの量をreduceする必要がありました。

maintenance_work_mem = 64MB     # min 1MB

以前は512MBでしたが、サーバーには32GBのRAM=がありましたが、それでも動作しませんでした。

5。)レクリエーションインデックス

結局、インデックスを再作成することが可能でした(古いものを削除して、新しいものを作成する)。適切なスクリプトを使用する方が簡単だったでしょうが、手動で実行する必要がありました。インデックスの作成と削除によりテーブルがロックされることを忘れないでください。(私のような)生産的な環境では、それを同時に実行する必要があります。

編集:

また、特定のケースでハッシュインデックスを使用することはあまり意味がないため、レクリエーション時にそれらをbtreeに変更することにしました。

6。)分析

インデックスを再作成した後、影響を受けるテーブル(またはDB全体)で分析を実行する必要があります。上記のすべてのアクションの後、それは私のような巨大なDBでも驚くほど速く実行されます。

インデックスが再び使用されており、パフォーマンスは再び完璧です。これは、私の最初のStackExchange投稿のハッピーエンドです。 :-)

6
wjozsi