Postgre データベースを大規模に運用している私たちからのよくある質問の 1 つは、
データベースの I/O 操作を最適化するにはどうすればよいですか?
歴史的に、Postgres サーバーによって生成される合計 I/O の全体像を取得するのは煩わしいものでした。 まず、Postgres は I/O プロセスを WAL ジョグの書き込みとナレッジ ディレクトリへの読み取り/書き込みに分割します。 正確な配信は、書き込みに関する 2d-explain 効果を解決することです: 一般に、ナレッジ ディレクトリへの書き込みは、トランザクションがコミットされた後に発生します。
プロビジョニングされた IOPS に直面した場合、またはさらに悪いことに、特定の人に支払う必要がある場合、この合計フィールドは、クラウド内で価値のあるより大きな配信に変わりました。 I/O は Amazon Aurora を愛用しています。 何度も何度も解決策は、インストルメンテーションを維持するシステムの部分を精査し (特定の人物のクエリのようにニュートラル)、プロセスがどこで進行するかについてある程度の意味を持っていることを示すことです.
週末の締めくくり、I/O プロセスへの可視性に対する重要な強化 以前はコミットされていました Andres Freund による次期 Postgres 16 に、Melanie Plageman と Samay Sharma によって作成されました。 私の同僚である Maciek Sakrejda と私は間違いなく、このパッチのさまざまなイテレーションを通してレビューを行ってきました。 )pg_stat_io。
のシークを魅せましょうPostgres でシステムの巨大な I/O 統計を照会する新たに構築されたローカル Postgres を使用して配信しようデパートメント。 Postgres 16 が重いパターンの下ではミュートであり、もはやベータ段階でさえないことを示してください。 このために、私は Meson kind システムの使用に関する新しいチートシート に従いました (これも Postgres 16 の新機能です)。のフォームとテスト コースを大幅に加速します。 )pg_stat_io は、知識が追跡されるテクニックを表し、空の行を省略します:
選択する * から pg_stat_io WHERE
reads
<> 0 OR 書き込み <> 0 O R が拡張 <> 0;
backend_type | io_object | io_context | 読む | 書き込みます | 拡張する | op_bytes | 立ち退き | 再利用 | fsync | fsync | stats_reset ----------------------+-----------------------+------------+-- --------+---------+---------+----------+---------- ------------+--------+-------------------------------- --- 自動バキュームランチャー | 関係 | 奇数 | 19 | 5 | | | 8192 | 13 | | | 0 | 2023-02-13 11:50:27.583875-08 オートバキューム社員 | 関係 | 奇数 | 15972 | 2494 | 2894 | 8192 | 17430 | | | 0 | 2023-02-13 11:50:27.583875-08 オートバキューム社員 | 関係 | 真空 | 5754853 | 3006563 | 0 | 8192 | 2056年 | 5752594 | | | 2023-02-13 11:50:27.583875-08 クライアント バックエンド | 関係 | 一括読み取り | 25832582 | 626900 | | | 8192 | 753962 | 25074439 | | | 2023-02-13 11:50:27.583875-08 クライアント バックエンド | 関係 | 一括書き込み | 4654 | 2858085 | 3259572 | 8192 | 998220 | 2209070 | | | 2023-02-13 11:50:27.583875-08 クライアント バックエンド | 関係 | 奇数 | 960291 | 376524 | 159497 | 8192 | 1103707 | | | 0 | 2023-02-13 11:50:27.583875-08 クライアント バックエンド | 関係 | 真空 | 128710 | 0 | 0 | 8192 | 1221 | 127489 | | | 2023-02-13 11:50:27.583875-08 バックグラウンド社員 | 関係 | 一括読み取り | 39059938 | 590896 | | | 8192 | 802939 | 38253662 | | | 2023-02-13 11:50:27.583875-08 バックグラウンド社員 | 関係 | 奇数 | 257533 | 118972 | 0 | 8192 | 256437 | | | 0 | 2023-02-13 11:50:27.583875-08 背景クリエーター | 関係 | 奇数 | | | 243142 | | | 8192 | | | | | 0 | 2023-02-13 11:50:27.583875-08 チェックポインター | 関係 | 奇数 | | | 390141 | | | 8192 | | | | | 18812 | 2023-02-13 11:50:27.583875-08 スタンドアロン バックエンド | 関係 | 一括書き込み | 0 | 0 | 8 | 8192 | 0 | 0 | | | 2023-02-13 11:50:27.583875-08 スタンドアロン バックエンド | 関係 | 奇数 | 689 | 983 | 470 | 8192 | 0 | | | 0 | 2023-02-13 11:50:27.583875-08 スタンドアロン バックエンド | 関係 | 真空 | 10 | 0 | 0 | 8192 | 0 | 0 | | | 2023-02-13 11:50:27.583875-08(14行)大まかに言うと、このレコードのデータは次のように解釈されます:
統計は、特定のバックエンドの種類、I/O オブジェクトの種類 (つまり、非永続テーブルであるかどうか)、および I/O コンテキスト (追加のテーブルであるかどうか) について追跡されます。後で) 最初の統計は、I/O 操作のカウントです: reads、writes および extends (ナレッジ レコードデータのサイズを変更するための紛れもない種類の書き込み) すべての I/O 操作のバイト単位のサイズは次のとおりです。統計を解釈するサービスを提供する名声 (現在、常にブロックサイズ、つまり、一般的に 8kB) さらに、共有バッファの削除、リング バッファの再利用、fsync 呼び出しの違いが追跡されますPostgres 16 では、この方法論に関する膨大な知識が常に市場で利用可能になります。 Postgresのドキュメント.
pg_stat_io であることを示すPostgres によって発行された論理 I/O 操作を明らかにします。 これは通常、最終的にディスクへの適切な I/O にマップされると同時に (特に書き込みの場合)、オペレーティング システムには独自のキャッシングおよびバッチ メカニズムがあり、通常インスタンスが分割されるときにニュートラルにすることもできます。ファイルシステムへの 4kB の書き込みを特定の 2 人に変更するための 8kB の書き込み。ために:
非永遠の記録データ (種類の時代遅れのような中立、または拡張子が崇拝 pg_stat_statements
)非永久世帯が追跡されていることを示す pg_stat_io
内これらは io_object="一時関係" としてマークされます -他の統計ビューでは、それらが「ネイティブ バッファ」として知られていることに注意してください。いくつかの怒鳴るケースを詳しく精査し、なぜこの問題が発生するのかを研究する立場にあります.
pg_stat_io の使用ケース Postgres での書き込み I/O プロセスの追跡 ライフサイクルPostgresでの書き込みの、そして現在ほとんどの統計では見えなくなっているもの Postgres の書き込みでシークを取得するとき、クイズ ランタイムまたは pg_stat_statements を調整できる何かを崇拝するため、買い物客が見るものを超えて精査する必要があります。 Postgres には、書き込みの堅牢性を保証するメカニズムの優れたビルドがありますが、クライアントは、サーバーが合意されたブレークプランで知識を保持していることを信頼して、フラッシュのように解放されます.
Postgresが知識を保持するために最初に行うことは、WALログに書き込むことです.これが成功するとすぐに、顧客は書き込みが行われたことの確認を取得します.安全。 それにもかかわらず、後で起こることは、追加の統計監視が手元にあるところです。 shared_blks_written フィールドは、正しい種類のナレッジ ディレクトリへの書き込みは、効率化のためにバッチ書き込みを説明し、I/O スパイクを回避するために、まれに後で発生します。
WAL の書き込みを開始するには、Postgres は、書き込み用に共有 (またはネイティブ) バッファを変更する可能性さえあります. このような変更は、クイズでバッファ ページを「ダーティ」としてマークします.
次に、最も連続して、ナレッジ ディレクトリにダーティ ページを書き込んでいることに疑いの余地はありません。 考慮すべき 3 つの主なコースがあります: はバックグラウンド クリエーター: 常にバックグラウンドで実行され、(一部の) ダーティ ページが書き出されます チェックポインタ: スケジュールされた基盤、または書き込まれた WAL の量に合わせて、まだ書き込まれていないすべてのダーティ ページを書き出します
その他のすべてのコース 、通常のクライアント バックエンドと一緒に: クイズでバッファ ページを削除したい場合は、ダーティ ページを書き出します最初に袋に入れておくべきことは、3 番目のケースが発生したときです。これは、 クエリが著しく緩んでいる ためです。 単純な「SELECT」でさえ、ディスクへの書き込みを認識せずに、その知識を読み取るために共有バッファーに十分に住むことを望む可能性があります.
歴史的には、 pg_stat_bgwriter
を通じて、このプロセスの一部を確認する準備がすでに整っています。 )、特に buffers_ という名前のフィールドを見つめます。 反対に、これは以前は不完全であり、自動バキューム プロセスを明示的に考慮していませんでした。また、書き込み (たとえば、バッファ With
pg_stat_io おそらく、writes を精査するだけの可能性もあります。 フィールドに入力し、事実に基づいた集計番号を両方ともマークします。Postgres のどのコースで、あなたの知識がディスクに書き込まれたことは間違いありません。
pg_stat_io
を明確にするのに役立ちます。これは、共有バッファー内のバッファー ページが追い出されるフィールドです。 共有バッファーは固定されたページの次元プールであるため (ほとんどの Postgres メソッドでは、それぞれの次元が 8kb ごとに)、内部にキャッシュされているものは山のような取引を発行します - 特に作業中のビルドが共有バッファーを超える場合.
デフォルトでは、たまたま自己管理型の Postgres を使用している場合はいつでも、
shared_buffers の設定は 128MB - または約 16,000 ページに決定されます。 非常に非効率なインデックス スキャンを介して何かを読み込んで停止し、128MB のすべてを魅了してしまったとしましょう。完全に多様化したもの? Postgres は、キャッシュからの古い知識のいくつかを切り替えて選択する必要があります。通常、バッファ ページの削除として識別されます。
この削除には 2 つの要素があります。主効果: 以前 Postgres バッファ キャッシュにあったデータは、そうすべきではありません。もはやキャッシュ内 (OS ページ キャッシュ内でミュート ミュートする可能性が高い) 以前は追い出されていたページが「ダーティ」としてマークされていた場合、追い出される過程はまた、廃止されたページをディスクに書き込む必要があります
共有バッファのサイジングに関するこれらのサブスタンス トピックの両方、およびpg_stat_io
は、監視することでこれについて明確に説明できます システム全体のすべてのバックエンドの種類に対するエビクション 。 さらに、エビクションの予想外の急増が発生した場合はいつでも、その後、reads
のヒープに気付かずに、以前は追い出されていたキャッシュされた知識が、その後急速に再び求められていたことを推測するのに役立ちます。 不確実な場合は、おそらく pg_buffercache も怒鳴る可能性があります。 真新しい共有バッファの内容を綿密に精査するための拡張機能.

追跡累積autovacuumとmanual VACUUMによるI/O処理すべての Postgres サーバーがときどき VACUUM を必要とすることは、長い道のりの真実です。手動でスケジュールを立てるか、自動バキュームを維持するかは関係ありません。 不要な行を簡単に整理し、住居を再利用可能にし、ページをフリーズしてトランザクション ID のラップアラウンドを防ぎます。 正確に調整されなくなった場合、VACUUM と自動バキュームは I/O プロセスで劇的な達成を維持できます。 歴史的に最も効果的な賭けは、log_autovacuum_min_duration の出力を精査することでした。 , これはこれを崇拝する知識を提供します:
ログ: テーブル "mydb.pg_toast. pg_toast_42593": インデックス スキャン: 0 ページ: 0 削除、13594 残り、13594 スキャン (合計の 100.00%)操作が終了した時点で廃止 新しい relfrozenxid: 11915、これは以前のコストよりも 4139 XID 進んでいます 凍結: テーブルからの 13594 ページ (合計の 100.00%) は 54515 のタプルを持っていました 凍結されたインデックス スキャンはもはや必要ありません: テーブルからの 0 ページ (合計の 0.00%) は無駄な商品 ID を 0 個排除 平均読み取り速度: 0.113 MB/秒、平均書き込み速度: 0.113 MB/秒 バッファ使用量: 13614 ヒット、13602 ミス、13600 ダーティ WAL 使用量: 40786 レコード、13600 の大量のページ写真、11 3072608 バイト システム使用量: CPU: クライアント: 0.26 秒、システム: 0.52 秒、経過: 939.84 秒
から バッファの使用法
おそらくそれを解決する可能性もありますこの 1 つの VACUUM は 13602 ページを読み取る必要があり、13600 ページをダーティとしてマークしました。 それにもかかわらず、すべての VACUUM にわたって追加の合計イメージを表現したい場合はどうすればよいでしょうか? With
pg_stat_io をシークすることで、VACUUM の影響のシステム規模の巨大な次元をおそらく見ることができるでしょう。 io_context='vacuum' とマークされたすべての小さなことで、または autovacuum employee バックエンドの種類に関連付けられています:
選択する
* から pg_stat_io
WHERE バックエンドの種類
=「autovacuum 従業員」 または (
io_c ontext =
「真空」
と
(reads <> 0 OR 書き込み <> 0 OR 拡張 <> 0));
backend_type | io_object | io_context | 読む | 書き込みます | 拡張する | op_bytes | 立ち退き | 再利用 | fsync | fsync | stats_reset --------------------+-----------------------+------------+--- ------+---------+---------+----------+-----------+ ------+--------------------+----------------------------------------------自動バキューム従業員 | 関係 | 一括読み取り | 0 | 0 | | | 8192 | 0 | 0 | | | 2023-02-13 11:50:27.583875-08 オートバキューム社員 | 関係 | 奇数 | 16306 | 2494 | 2915年 | 8192 | 17785 | | | 0 | 2023-02-13 11:50:27.583875-08 オートバキューム社員 | 関係 | 真空 | 5824251 | 3028684 | 0 | 8192 | 2588 | 5821460 | | | 2023-02-13 11:50:27.583875-08 クライアント バックエンド | 関係 | 真空 | 128710 | 0 | 0 | 8192 | 1221 | 127489 | | | 2023-02-13 11:50:27.583875-08 スタンドアロン バックエンド | 関係 | 真空 | 10 | 0 | 0 | 8192 | 0 | 0 | | | 2023-02-13 11:50:27.583875-08(5行)この特定の例では、要約すると、 autovacuum の従業員は、44.4 GB の知識 (5,824,251 バッファー ページ) を読み取り、23.1 GB (3,028,684 バッファー ページ) を書き込みました。
これらの統計を調整するとすぐに時間 、これはおそらく、自動バキュームがエンタープライズ時間の長さの I/O スパイクの原因であるかどうかの非常に具体的なイメージを維持する立場にあるのに役立つ可能性があります。 これはニュートラルであり、自動バキュームをさらに自信を持って調整するための担当者の変更にも役立ちます。
一括読み取り/書き込み方法 (シーケンシャル スキャンと COPY) の可視性
知識をロードするために Postgres の COPY を時代遅れにしたことがありますか? または、シーケンシャル スキャンを使用してテーブルから知識を読み取りますか? また、ニュートラルは、通常の方法論では共有バッファーを介してシャッフルされないことを常に認識していない可能性があります。 異なる点として、Postgres は否定できない専用のリング バッファーを使用しており、共有バッファーのほぼすべてがそのような大規模なアクティビティによって妨げられないようにしています
ahead of
pg_stat_io, Postgres でこのプロセスをバギングすることは不可能に閉ざされていました. 以前は監視がなかっただけです。 現在、最終的には、バルク読み取り (まれに大規模なシーケンシャル スキャン) とバルク書き込み (まれに COPY in) の両方と、それらが動機とする I/O プロセスを確認できる立場にあります。 また、新しい
bulkwrite をフィルタリングすることもできます。 bulkread の値 io_context、およびこのプロセスへの可視性を維持します: 選択する * から pg_stat_io WHERE io_context IN ('バルクリード'
,
'一括書き込み') と (reads <> 0 OR 書き込み <> 0 OR 拡張 <> 0);
backend_type | io_object | io_context | 読む | 書き込みます | 拡張する | op_bytes | 立ち退き | 再利用 | fsync | fsync | stats_reset --------------------+-----------------------+------------+--- -------+---------+---------+----------+----------- +---------+--------------------+--------------------------------- -- クライアント バックエンド | 関係 | 一括読み取り | 25900458 | 627059 | | | 8192 | 754610 | 25141667 | | | 2023-02-13 11:50:27.583875-08 クライアント バックエンド | 関係 | 一括書き込み | 4654 | 2858085 | 3259572 | 8192 | 998220 | 2209070 | | | 2023-02-13 11:50:27.583875-08 バックグラウンド社員 | 関係 | 一括読み取り | 39059938 | 590896 | | | 8192 | 802939 | 38253662 | | | 2023-02-13 11:50:27.583875-08 スタンドアロン バックエンド | 関係 | 一括書き込み | 0 | 0 | 8 | 8192 | 0 | 0 | | | 2023-02-13 11:50:27.583875-08(4行)この状況では、495 GB のバルクがあります読み取りプロセス、および 21 GB の一括書き込みプロセスについては、事前に把握する正しい方法論がありませんでした。 反対に、最も深刻なことに、立ち退きについては強調したくありません。 ここに依存 - これらはすべて、通常の共有バッファからではなく、特別なバルク読み取り/バルク書き込みリング バッファからのエビクションです。
スニークピーク: pganalyze で pg_stat_io を視覚化するPostgres 16 になるまではミュートです(通常は毎年 9 月または 10 月) が開始されましたが、テストの問題を提供するためです (そして、その結果は興味深いものです!) 実験部門で pganalyze の更新に簡単に挑戦しました
pg_stat_io を決定する ここでは、これがどのように休憩時間内にニュートラルな崇拝を精査できるかについて、非常に初期の精査です:
時間とともに my pc pc, すでに、チェックポインターとバックグラウンド クリエーター プロセスによって書き込みが実行されている明確なサンプルを確認する立場にあります。 さらに、私の checkpoint_timeout も確認できる立場にあります。 5min (デフォルト) までビルドされます。 書き込みと fsync は時計仕掛けを崇拝します - ワークロードは 10 分ごとに周期的であるため、2 番目のチェックポイントごとに実行する作業が大幅に少なくなります 反対に、プロセスのスパイクもはっきりと確認できる立場にあります - そして、そのスパイクは明確に定義されていません: 8: 午後 10 時 (UTC)。 大量のナレッジ読み取りにより、作業中のビルドが一時的に共有バッファーを超え、膨大な量のバッファー エビクションが発生し、顧客のバックエンドが気付かないうちにバッファー ページを書き出さなければならなくなりました.
この方法論では、私は間違いなく非常に小さな
shared_buffers 設定 (デフォルト、128 MB)。 私は間違いなく、より大きなshared_buffersを担当することをミュートする必要があります... 
Postgres における I/O オブザーバビリティの方法論 Loads of the ground work for pg_stat_io Postgres 15 では、新しい累積統計システムを通じて共有メモリを使用することで、事前に状態を取得していたことは間違いありません。
Postgres 15 に先立って、統計の監視は統計コレクター (Postgres の特定のユーザー プロセス セクションから UDP パケットを取得する不正確な過程) を介して戦争をしなければなりませんでした。傾いた。 これにより、歴史的に、余分に開発された統計を簡単に決定する柔軟性が制限されていました。 pg_stat_io
を追加したことで明らかになったので、より価値のあるものになりましたPostgres がどのように動作するかについての余分な知識を追跡するのは簡単です。 の追跡system-huge buffer cache hits (実際のバッファ キャッシュ ヒット率を計算できるようにするため)
累積的なシステムの巨大な I/O 時間 (現在の画面のように素晴らしい I/O はカウントされません pg_stat_io
) 累積WALが高い統計 (つまり、pg_stat_wal が提供するものを超える) テーブルとインデックスの追加の I/O 監視 pganalyze のスタッフは、維持することに憤慨しています。ブランドの新しい形成に役立ちました pg_stat_io じっと見つめて、作業を進めるために精査しますPostgres をより良くするためのコミュニティです。 ツイートはこちら
.
PS: 出来次第また、Postgres の I/O パフォーマンスとコストの最適化についてさらに勉強することになる可能性があります。おそらく ウェビナーの録画をご覧ください .
pganalyzeニュースレターの支払い
注目を集める Postgres が担当者全体に与えること、新しい pganalyze の特徴的なリリース、新しい pganalyze の電子ブックに関するまれなメールを受け取ります。 未承諾メールはありません。
>
𝚆𝚊𝚝𝚌𝚑 𝙽𝙾𝚆 📺
新たに構築されたローカル Postgres を使用して配信しようデパートメント。 Postgres 16 が重いパターンの下ではミュートであり、もはやベータ段階でさえないことを示してください。 このために、私は Meson kind システムの使用に関する新しいチートシート に従いました (これも Postgres 16 の新機能です)。のフォームとテスト コースを大幅に加速します。 )pg_stat_io は、知識が追跡されるテクニックを表し、空の行を省略します:
選択する*から pg_stat_io WHEREreads
<> 0 OR 書き込み <> 0 O R が拡張 <> 0;
backend_type | io_object | io_context | 読む | 書き込みます | 拡張する | op_bytes | 立ち退き | 再利用 | fsync | fsync | stats_reset ----------------------+-----------------------+------------+-- --------+---------+---------+----------+---------- ------------+--------+-------------------------------- --- 自動バキュームランチャー | 関係 | 奇数 | 19 | 5 | | | 8192 | 13 | | | 0 | 2023-02-13 11:50:27.583875-08 オートバキューム社員 | 関係 | 奇数 | 15972 | 2494 | 2894 | 8192 | 17430 | | | 0 | 2023-02-13 11:50:27.583875-08 オートバキューム社員 | 関係 | 真空 | 5754853 | 3006563 | 0 | 8192 | 2056年 | 5752594 | | | 2023-02-13 11:50:27.583875-08 クライアント バックエンド | 関係 | 一括読み取り | 25832582 | 626900 | | | 8192 | 753962 | 25074439 | | | 2023-02-13 11:50:27.583875-08 クライアント バックエンド | 関係 | 一括書き込み | 4654 | 2858085 | 3259572 | 8192 | 998220 | 2209070 | | | 2023-02-13 11:50:27.583875-08 クライアント バックエンド | 関係 | 奇数 | 960291 | 376524 | 159497 | 8192 | 1103707 | | | 0 | 2023-02-13 11:50:27.583875-08 クライアント バックエンド | 関係 | 真空 | 128710 | 0 | 0 | 8192 | 1221 | 127489 | | | 2023-02-13 11:50:27.583875-08 バックグラウンド社員 | 関係 | 一括読み取り | 39059938 | 590896 | | | 8192 | 802939 | 38253662 | | | 2023-02-13 11:50:27.583875-08 バックグラウンド社員 | 関係 | 奇数 | 257533 | 118972 | 0 | 8192 | 256437 | | | 0 | 2023-02-13 11:50:27.583875-08 背景クリエーター | 関係 | 奇数 | | | 243142 | | | 8192 | | | | | 0 | 2023-02-13 11:50:27.583875-08 チェックポインター | 関係 | 奇数 | | | 390141 | | | 8192 | | | | | 18812 | 2023-02-13 11:50:27.583875-08 スタンドアロン バックエンド | 関係 | 一括書き込み | 0 | 0 | 8 | 8192 | 0 | 0 | | | 2023-02-13 11:50:27.583875-08 スタンドアロン バックエンド | 関係 | 奇数 | 689 | 983 | 470 | 8192 | 0 | | | 0 | 2023-02-13 11:50:27.583875-08 スタンドアロン バックエンド | 関係 | 真空 | 10 | 0 | 0 | 8192 | 0 | 0 | | | 2023-02-13 11:50:27.583875-08(14行)
(
大まかに言うと、このレコードのデータは次のように解釈されます:
統計は、特定のバックエンドの種類、I/O オブジェクトの種類 (つまり、非永続テーブルであるかどうか)、および I/O コンテキスト (追加のテーブルであるかどうか) について追跡されます。後で) 最初の統計は、I/O 操作のカウントです: reads、writes および extends (ナレッジ レコードデータのサイズを変更するための紛れもない種類の書き込み) すべての I/O 操作のバイト単位のサイズは次のとおりです。統計を解釈するサービスを提供する名声 (現在、常にブロックサイズ、つまり、一般的に 8kB) さらに、共有バッファの削除、リング バッファの再利用、fsync 呼び出しの違いが追跡されます
Postgres 16 では、この方法論に関する膨大な知識が常に市場で利用可能になります。 Postgresのドキュメント.
pg_stat_ioであることを示すPostgres によって発行された論理 I/O 操作を明らかにします。 これは通常、最終的にディスクへの適切な I/O にマップされると同時に (特に書き込みの場合)、オペレーティング システムには独自のキャッシングおよびバッチ メカニズムがあり、通常インスタンスが分割されるときにニュートラルにすることもできます。ファイルシステムへの 4kB の書き込みを特定の 2 人に変更するための 8kB の書き込み。ために:非永遠の記録データ (種類の時代遅れのような中立、または拡張子が崇拝)pg_stat_statements非永久世帯が追跡されていることを示す
pg_stat_io
内これらはio_object="一時関係"としてマークされます -他の統計ビューでは、それらが「ネイティブ バッファ」として知られていることに注意してください。いくつかの怒鳴るケースを詳しく精査し、なぜこの問題が発生するのかを研究する立場にあります.pg_stat_io の使用ケース Postgres での書き込み I/O プロセスの追跡 ライフサイクルPostgresでの書き込みの、そして現在ほとんどの統計では見えなくなっているもの Postgres の書き込みでシークを取得するとき、クイズ ランタイムまたは pg_stat_statements を調整できる何かを崇拝するため、買い物客が見るものを超えて精査する必要があります。 Postgres には、書き込みの堅牢性を保証するメカニズムの優れたビルドがありますが、クライアントは、サーバーが合意されたブレークプランで知識を保持していることを信頼して、フラッシュのように解放されます.
Postgresが知識を保持するために最初に行うことは、WALログに書き込むことです.これが成功するとすぐに、顧客は書き込みが行われたことの確認を取得します.安全。 それにもかかわらず、後で起こることは、追加の統計監視が手元にあるところです。 shared_blks_written
フィールドは、正しい種類のナレッジ ディレクトリへの書き込みは、効率化のためにバッチ書き込みを説明し、I/O スパイクを回避するために、まれに後で発生します。
WAL の書き込みを開始するには、Postgres は、書き込み用に共有 (またはネイティブ) バッファを変更する可能性さえあります. このような変更は、クイズでバッファ ページを「ダーティ」としてマークします.
次に、最も連続して、ナレッジ ディレクトリにダーティ ページを書き込んでいることに疑いの余地はありません。 考慮すべき 3 つの主なコースがあります: はバックグラウンド クリエーター: 常にバックグラウンドで実行され、(一部の) ダーティ ページが書き出されます チェックポインタ: スケジュールされた基盤、または書き込まれた WAL の量に合わせて、まだ書き込まれていないすべてのダーティ ページを書き出します
その他のすべてのコース 、通常のクライアント バックエンドと一緒に: クイズでバッファ ページを削除したい場合は、ダーティ ページを書き出します最初に袋に入れておくべきことは、3 番目のケースが発生したときです。これは、 クエリが著しく緩んでいる ためです。 単純な「SELECT」でさえ、ディスクへの書き込みを認識せずに、その知識を読み取るために共有バッファーに十分に住むことを望む可能性があります.
歴史的には、
pg_stat_bgwriter
を通じて、このプロセスの一部を確認する準備がすでに整っています。 )、特にbuffers_
という名前のフィールドを見つめます。 反対に、これは以前は不完全であり、自動バキューム プロセスを明示的に考慮していませんでした。また、書き込み (たとえば、バッファWith
pg_stat_io おそらく、writesを精査するだけの可能性もあります。 フィールドに入力し、事実に基づいた集計番号を両方ともマークします。Postgres のどのコースで、あなたの知識がディスクに書き込まれたことは間違いありません。
pg_stat_io
を明確にするのに役立ちます。これは、共有バッファー内のバッファー ページが追い出されるフィールドです。 共有バッファーは固定されたページの次元プールであるため (ほとんどの Postgres メソッドでは、それぞれの次元が 8kb ごとに)、内部にキャッシュされているものは山のような取引を発行します - 特に作業中のビルドが共有バッファーを超える場合.デフォルトでは、たまたま自己管理型の Postgres を使用している場合はいつでも、
shared_buffersの設定は 128MB - または約 16,000 ページに決定されます。 非常に非効率なインデックス スキャンを介して何かを読み込んで停止し、128MB のすべてを魅了してしまったとしましょう。完全に多様化したもの? Postgres は、キャッシュからの古い知識のいくつかを切り替えて選択する必要があります。通常、バッファ ページの削除として識別されます。
この削除には 2 つの要素があります。主効果: 以前 Postgres バッファ キャッシュにあったデータは、そうすべきではありません。もはやキャッシュ内 (OS ページ キャッシュ内でミュート ミュートする可能性が高い) 以前は追い出されていたページが「ダーティ」としてマークされていた場合、追い出される過程はまた、廃止されたページをディスクに書き込む必要があります
共有バッファのサイジングに関するこれらのサブスタンス トピックの両方、およびpg_stat_io
は、監視することでこれについて明確に説明できますシステム全体のすべてのバックエンドの種類に対するエビクション
のヒープに気付かずに、以前は追い出されていたキャッシュされた知識が、その後急速に再び求められていたことを推測するのに役立ちます。 不確実な場合は、おそらく。 さらに、エビクションの予想外の急増が発生した場合はいつでも、その後、readspg_buffercache も怒鳴る可能性があります。 真新しい共有バッファの内容を綿密に精査するための拡張機能.
![]()
追跡累積autovacuumとmanual VACUUMによるI/O処理
すべての Postgres サーバーがときどき VACUUM を必要とすることは、長い道のりの真実です。手動でスケジュールを立てるか、自動バキュームを維持するかは関係ありません。 不要な行を簡単に整理し、住居を再利用可能にし、ページをフリーズしてトランザクション ID のラップアラウンドを防ぎます。 正確に調整されなくなった場合、VACUUM と自動バキュームは I/O プロセスで劇的な達成を維持できます。 歴史的に最も効果的な賭けは、
log_autovacuum_min_duration の出力を精査することでした。 , これはこれを崇拝する知識を提供します:
ログ: テーブル "mydb.pg_toast. pg_toast_42593": インデックス スキャン: 0 ページ: 0 削除、13594 残り、13594 スキャン (合計の 100.00%)操作が終了した時点で廃止 新しい relfrozenxid: 11915、これは以前のコストよりも 4139 XID 進んでいます 凍結: テーブルからの 13594 ページ (合計の 100.00%) は 54515 のタプルを持っていました 凍結されたインデックス スキャンはもはや必要ありません: テーブルからの 0 ページ (合計の 0.00%) は無駄な商品 ID を 0 個排除 平均読み取り速度: 0.113 MB/秒、平均書き込み速度: 0.113 MB/秒 バッファ使用量: 13614 ヒット、13602 ミス、13600 ダーティ WAL 使用量: 40786 レコード、13600 の大量のページ写真、11 3072608 バイト システム使用量: CPU: クライアント: 0.26 秒、システム: 0.52 秒、経過: 939.84 秒
から
バッファの使用法
おそらくそれを解決する可能性もありますこの 1 つの VACUUM は 13602 ページを読み取る必要があり、13600 ページをダーティとしてマークしました。 それにもかかわらず、すべての VACUUM にわたって追加の合計イメージを表現したい場合はどうすればよいでしょうか?With
pg_stat_ioをシークすることで、VACUUM の影響のシステム規模の巨大な次元をおそらく見ることができるでしょう。
io_context='vacuum'
とマークされたすべての小さなことで、またはautovacuum employee
バックエンドの種類に関連付けられています:選択する
* から pg_stat_io
WHERE
バックエンドの種類 =「autovacuum 従業員」または (io_c ontext =
「真空」と
reads <> 0OR 書き込み <> 0 OR 拡張 <> 0));
backend_type | io_object | io_context | 読む | 書き込みます | 拡張する | op_bytes | 立ち退き | 再利用 | fsync | fsync | stats_reset --------------------+-----------------------+------------+--- ------+---------+---------+----------+-----------+ ------+--------------------+----------------------------------------------自動バキューム従業員 | 関係 | 一括読み取り | 0 | 0 | | | 8192 | 0 | 0 | | | 2023-02-13 11:50:27.583875-08 オートバキューム社員 | 関係 | 奇数 | 16306 | 2494 | 2915年 | 8192 | 17785 | | | 0 | 2023-02-13 11:50:27.583875-08 オートバキューム社員 | 関係 | 真空 | 5824251 | 3028684 | 0 | 8192 | 2588 | 5821460 | | | 2023-02-13 11:50:27.583875-08 クライアント バックエンド | 関係 | 真空 | 128710 | 0 | 0 | 8192 | 1221 | 127489 | | | 2023-02-13 11:50:27.583875-08 スタンドアロン バックエンド | 関係 | 真空 | 10 | 0 | 0 | 8192 | 0 | 0 | | | 2023-02-13 11:50:27.583875-08(5行)
この特定の例では、要約すると、 autovacuum の従業員は、44.4 GB の知識 (5,824,251 バッファー ページ) を読み取り、23.1 GB (3,028,684 バッファー ページ) を書き込みました。
これらの統計を調整するとすぐに時間 、これはおそらく、自動バキュームがエンタープライズ時間の長さの I/O スパイクの原因であるかどうかの非常に具体的なイメージを維持する立場にあるのに役立つ可能性があります。 これはニュートラルであり、自動バキュームをさらに自信を持って調整するための担当者の変更にも役立ちます。
一括読み取り/書き込み方法 (シーケンシャル スキャンと COPY) の可視性
知識をロードするために Postgres の COPY を時代遅れにしたことがありますか? または、シーケンシャル スキャンを使用してテーブルから知識を読み取りますか? また、ニュートラルは、通常の方法論では共有バッファーを介してシャッフルされないことを常に認識していない可能性があります。 異なる点として、Postgres は否定できない専用のリング バッファーを使用しており、共有バッファーのほぼすべてがそのような大規模なアクティビティによって妨げられないようにしています
ahead of
pg_stat_io, Postgres でこのプロセスをバギングすることは不可能に閉ざされていました. 以前は監視がなかっただけです。 現在、最終的には、バルク読み取り (まれに大規模なシーケンシャル スキャン) とバルク書き込み (まれに COPY in) の両方と、それらが動機とする I/O プロセスを確認できる立場にあります。また、新しい
bulkwriteをフィルタリングすることもできます。bulkread
の値 io_context
、およびこのプロセスへの可視性を維持します:選択する* から pg_stat_io WHEREio_context IN ('バルクリード',
'一括書き込み') と (reads <>0 OR 書き込み <> 0 OR 拡張 <> 0);
backend_type | io_object | io_context | 読む | 書き込みます | 拡張する | op_bytes | 立ち退き | 再利用 | fsync | fsync | stats_reset --------------------+-----------------------+------------+--- -------+---------+---------+----------+----------- +---------+--------------------+--------------------------------- -- クライアント バックエンド | 関係 | 一括読み取り | 25900458 | 627059 | | | 8192 | 754610 | 25141667 | | | 2023-02-13 11:50:27.583875-08 クライアント バックエンド | 関係 | 一括書き込み | 4654 | 2858085 | 3259572 | 8192 | 998220 | 2209070 | | | 2023-02-13 11:50:27.583875-08 バックグラウンド社員 | 関係 | 一括読み取り | 39059938 | 590896 | | | 8192 | 802939 | 38253662 | | | 2023-02-13 11:50:27.583875-08 スタンドアロン バックエンド | 関係 | 一括書き込み | 0 | 0 | 8 | 8192 | 0 | 0 | | | 2023-02-13 11:50:27.583875-08(4行)
この状況では、495 GB のバルクがあります読み取りプロセス、および 21 GB の一括書き込みプロセスについては、事前に把握する正しい方法論がありませんでした。 反対に、最も深刻なことに、
立ち退き
については強調したくありません。 ここに依存 - これらはすべて、通常の共有バッファからではなく、特別なバルク読み取り/バルク書き込みリング バッファからのエビクションです。
Postgres 16 になるまではミュートです(通常は毎年 9 月または 10 月) が開始されましたが、テストの問題を提供するためです (そして、その結果は興味深いものです!) 実験部門で pganalyze の更新に簡単に挑戦しました
pg_stat_ioを決定するここでは、これがどのように休憩時間内にニュートラルな崇拝を精査できるかについて、非常に初期の精査です:
時間とともに my pc pc, すでに、チェックポインターとバックグラウンド クリエーター プロセスによって書き込みが実行されている明確なサンプルを確認する立場にあります。 さらに、私のcheckpoint_timeoutも確認できる立場にあります。5min(デフォルト) までビルドされます。 書き込みと fsync は時計仕掛けを崇拝します - ワークロードは 10 分ごとに周期的であるため、2 番目のチェックポイントごとに実行する作業が大幅に少なくなります反対に、プロセスのスパイクもはっきりと確認できる立場にあります - そして、そのスパイクは明確に定義されていません: 8: 午後 10 時 (UTC)。 大量のナレッジ読み取りにより、作業中のビルドが一時的に共有バッファーを超え、膨大な量のバッファー エビクションが発生し、顧客のバックエンドが気付かないうちにバッファー ページを書き出さなければならなくなりました.
この方法論では、私は間違いなく非常に小さな
shared_buffers 設定 (デフォルト、128 MB)。 私は間違いなく、より大きなshared_buffersを担当することをミュートする必要があります...Postgres における I/O オブザーバビリティの方法論 Loads of the ground work for
pg_stat_io Postgres 15 では、新しい累積統計システムを通じて共有メモリを使用することで、事前に状態を取得していたことは間違いありません。Postgres 15 に先立って、統計の監視は統計コレクター (Postgres の特定のユーザー プロセス セクションから UDP パケットを取得する不正確な過程) を介して戦争をしなければなりませんでした。傾いた。 これにより、歴史的に、余分に開発された統計を簡単に決定する柔軟性が制限されていました。
pg_stat_io
を追加したことで明らかになったので、より価値のあるものになりましたPostgres がどのように動作するかについての余分な知識を追跡するのは簡単です。 の追跡system-huge buffer cache hits (実際のバッファ キャッシュ ヒット率を計算できるようにするため)累積的なシステムの巨大な I/O 時間 (現在の画面のように素晴らしい I/O はカウントされません pg_stat_io
) 累積WALが高い統計 (つまり、pg_stat_wal が提供するものを超える) テーブルとインデックスの追加の I/O 監視.pganalyze のスタッフは、維持することに憤慨しています。ブランドの新しい形成に役立ちました
pg_stat_io
じっと見つめて、作業を進めるために精査しますPostgres をより良くするためのコミュニティです。 ツイートはこちらPS: 出来次第また、Postgres の I/O パフォーマンスとコストの最適化についてさらに勉強することになる可能性があります。おそらく ウェビナーの録画をご覧ください .
pganalyzeニュースレターの支払い
注目を集める Postgres が担当者全体に与えること、新しい pganalyze の特徴的なリリース、新しい pganalyze の電子ブックに関するまれなメールを受け取ります。 未承諾メールはありません。
>
𝚆𝚊𝚝𝚌𝚑 𝙽𝙾𝚆 📺