PostgreSQLデプロイメントのどのメトリックを監視する必要がありますか?この一連のブログ投稿は、Postgresサーバーの正常性と安定性を確保するために実装する必要のある基本的な監視アクションの最小限の開始セットを提供することを目的としています。
これはブログシリーズの第2部であり、データベースレベルのパラメーターについて説明しています。最初の部分ではクラスターレベルのパラメーターについて説明しています。
パート2:データベースレベル
このパートでは、使用する重要なデータベースごとに監視する必要のあるメトリックと情報について説明します。
以下にリストされているSQLクエリのほとんどは、問題のデータベースに接続しているときに実行する必要があります。
1。接続されたクライアント
接続されたクライアントは、OSとシステムのリソースを消費します。 Postgresにはクライアントごとのプロセスアーキテクチャがあり、クライアントが多すぎるとクエリの応答時間が永久に遅くなる可能性があります。 PgBouncer orpgpoolを使用して、Postgresサーバーが処理する必要のある接続の数を減らすことを検討してください。
アプリケーションの更新後のベースラインの変化と、トラフィックの増加による接続の急増に注意してください。
アクション:1日/週ごとに接続されているクライアントの最大数を監視し、傾向の変化を調査します。
方法:
-- returns the number of clients connected for each database
SELECT datname, count(*)
FROM pg_stat_activity
GROUP BY datname;
2。サイズ
データベースで使用される実際のディスクサイズを監視する必要があります。ほとんどの場合、データベースのサイズは増え続けているため、より興味深いのは成長率です。繰り返しになりますが、新しいアプリケーションのリリース後の成長率の増加には注意してください。
アクション:毎週/月ごとにデータベースのサイズの増加を監視し、傾向を調査し、再プロビジョニングします。
方法:
-- returns the size for each database
SELECT datname, pg_size_pretty(pg_database_size(datname))
FROM pg_database;
3。すべてのテーブルでテーブルが膨らむ
PostgresのMVCCアーキテクチャにより、古いバージョンの行はすべてのテーブルの物理データファイルに存在し、膨張と呼ばれます。 。廃止された行バージョンをクリアする操作は、バキュームと呼ばれます。 。 Postgresはautovacuumと呼ばれるバックグラウンドプロセスを実行します 、(構成可能なパラメーターに基づいて)候補テーブルを取得し、それらをバキュームします。
Bloatはテーブルの動作を遅くし、ディスクスペースを浪費し、自動真空でも逃げる可能性があります。膨張の監視は、絶対バイト数および(データ全体に対するデッドデータの)パーセンテージとして必要です。これは、データベースレベルですべてのテーブルの合計として実行でき、「最も肥大化したテーブル」にドリルダウンする可能性があります。
アクション:総膨張をバイトとパーセンテージで継続的に監視し、値が設定されたしきい値を超えた場合にアラートを出します。
方法:
check_postgres orpgmetricsを使用して、肥大化の見積もりを取得します。詳細については、wikiを参照してください。
4。すべてのインデックスにわたるインデックスの膨張
肥大化したインデックスは、挿入を遅くし、ルックアップのパフォーマンスを低下させる可能性があります。インデックスの肥大化を絶対値(バイト数)とパーセンテージの両方として監視します。インデックスが肥大化しすぎた場合は、インデックスを再構築する必要があります。
アクション:総膨張をバイトとパーセンテージで継続的に監視し、値が設定されたしきい値を超えた場合にアラートを出します。
方法:
check_postgres orpgmetricsを使用して、肥大化の見積もりを取得します。詳細については、wikiを参照してください。
5。長時間実行されるトランザクション
あまりにも長い間開いているトランザクションは、PostgreSQLにとって良いニュースではありません。長時間実行されるトランザクションは、WALファイルの保持を引き起こし、ロックを保持し、真空を防ぐ可能性があります。アプリケーションは、トランザクション期間をできるだけ短くするように設計する必要があります。
長時間実行されるトランザクションを実行しているバックエンドは、 pg_cancel_backend()を使用して強制終了できます。 およびpg_terminate_backend() 機能。
アクション:設定された期間を超えて実行されているトランザクションの数を継続的に監視し、値が設定されたしきい値を超えた場合にアラートを出します。
方法:
-- returns the count of transactions that have been running for more than a day
SELECT count(*)
FROM pg_stat_activity
WHERE xact_start < now() - '24 hours'::interval;
6。デッドロック
PostgreSQLでは、バックエンドは、行を変更するクエリを実行するときに、行とテーブルを暗黙的にロックします。クエリは、明示的なロックを設定することもできます( SELECT .. FOR UPDATE など) )。マルチスレッドプログラミングの場合と同様に、暗黙的または明示的に逆の順序でロックを配置する2つのトランザクションにより、デッドロックが発生する可能性があります。
PostgreSQLはデッドロックを検出し、関連するトランザクションの1つをロールバックします(トランザクションによって保持されているすべてのロックは、コミットまたはロールバックされると解放されます)。詳細はPostgreSQLのログ先に記録されます。
アプリケーションは、デッドロックの可能性を回避するように設計する必要があります。デッドロックが発生した場合にトランザクションを再試行することもできます。
アクション:毎日/週のデッドロックカウントを監視し、アプリケーションを再設計してカウントを減らし、変更を調査します。
方法:
デッドロックの発生は、追加情報とともに、PostgreSQLログファイルに記録されます。この情報を抽出するには、pgmetrics、pgbadger、またはその他のPostgreSQL固有のログ処理ツールを使用します。
7。最古の掃除機
自動バキュームまたはスケジュールされたジョブのいずれかを使用した、または手動でのテーブルの定期的なバキュームは、テーブルの操作を高速に保つために必須です。ただし、長時間実行されるトランザクション、非アクティブなレプリケーションスロットなど、さまざまな理由でバキュームが失敗する可能性があります。
Postgresの世界では、テーブルを定期的にバキュームすることが非常に重要であるため、すべてのテーブルが設定された間隔で少なくとも1回バキュームされているかどうかを定期的にチェックするのが最善です。
そして、それらは見えなくなり、頭に浮かぶ傾向がありますが、システムカタログテーブルも真空にする必要があります。
アクション:最後に設定された時間/日数の間にテーブルがバキュームされていないかどうかを継続的に確認し、ある場合はアラートを出します。
方法:
-- returns the top 5 tables vacuumed least recently
SELECT schemaname || '.' || relname, now()-last_vacuum
FROM pg_stat_all_tables
ORDER BY last_vacuum ASC NULLS LAST LIMIT 5;
-- returns all tables that have not been vacuumed in the last 7 days
SELECT schemaname || '.' || relname, now()-last_vacuum
FROM pg_stat_all_tables
WHERE last_vacuum < now() - '7 days'::interval;
8。最古の分析
SELECTクエリを実行するには、クエリプランナー 実行計画を作成します 読み取る必要のあるインデックスとテーブル、およびその方法を記述します。効率的な実行プランを作成するには、プランナーは値の分布、タプルのサイズなどに関する統計を持っている必要があります。テーブル内のデータに関するこのような統計情報は、分析によって収集および維持されます。 オペレーション。最新の統計を含むテーブルを使用すると、クエリが高速になり、I/Oが少なくなります。
上記の自動真空プロセスは、通常、 ANALYZEも実行します。 テーブル上では、この情報を最新の状態に保つために掃除機をかけます。ただし、これだけでは、テーブルに十分な分析カバレッジが提供されない場合があります。 ANALYZEをスケジュールされたジョブとして実行するか、テーブルを大幅に変更した後に補足する必要があります。
クエリのパフォーマンスを向上させるために、すべてのテーブルが設定された間隔で少なくとも1回分析されているかどうかを継続的にチェックすることをお勧めします。
アクション:最後に設定された時間/日数で分析されていないテーブルがあるかどうかを継続的に確認し、分析されている場合はアラートを送信します。
方法:
-- returns the top 5 tables analyzed least recently
SELECT schemaname || '.' || relname, now()-last_analyze
FROM pg_stat_all_tables
ORDER BY last_analyze ASC NULLS LAST LIMIT 5;
-- returns all tables that have not been analyzed in the last 7 days
SELECT schemaname || '.' || relname, now()-last_analyze
FROM pg_stat_all_tables
WHERE last_analyze < now() - '7 days'::interval;
上記のセクションでは、実行中のPostgresサーバーから必要なメトリックを抽出するためのSQLステートメントを提供します。スクリプトを自分で作成したくない場合は、オープンソースツールのpgmetricsを確認してください。上記の指標などを収集し、テキストおよびJSON形式でレポートできます。
pgmetricsレポートを当社の商用サービスであるpgDashに直接送信できます。pgDashは、これらのレポートを保存および処理して、グラフを表示し、アラートを実行します。
このシリーズの次のパートでは、テーブルレベル、インデックスレベル、およびシステムレベルのメトリックについて説明します。しばらくお待ちください!