最新のRDBMSとして、PostgreSQLには微調整のための多くのパラメーターが付属しています。考慮すべき領域の1つは、PostgreSQLがそのアクティビティをログに記録する方法です。ロギングはPostgresデータベース管理で見過ごされがちであり、無視されない場合、通常は誤って設定されます。これは、ほとんどの場合、ロギングの目的が不明確であるために発生します。もちろん、ロギングの根本的な理由はよく知られていますが、ログがどのように使用されるかを理解していないことがあります。
各組織のログ要件は固有であるため、PostgreSQLログの構成方法も異なります。金融サービス会社がデータベースログにキャプチャする必要があるものは、重要な健康情報を扱う会社が記録する必要があるものとは異なります。また、場合によっては、それらも類似している可能性があります。
この記事では、PostgreSQLログを最大限に活用するためのいくつかの基本的なプラクティスについて説明します。このブログは、厳格で迅速なルールブックではありません。読者はコメントセクションで彼らの考えを共有することを歓迎します。ただし、最高の価値を引き出すために、読者にPostgreSQLデータベースサーバーのログをどのように使用したいかを考えてもらいます。
- 特定の情報を取得する必要がある法令遵守の理由
- 特定のイベントの詳細を提示する必要がある場合のセキュリティ監査
- クエリとそのパラメータを記録するパフォーマンスのトラブルシューティング
- 設定された数の指標を監視する日常の運用サポート
それでは、始めましょう。
postgresql.confに手動で変更を加えないでください
postgresql.confファイルの変更は、Puppet、Ansible、Chefなどの構成管理システムを使用して行う必要があります。これにより、変更を追跡可能にし、必要に応じて以前のバージョンに安全にロールバックできます。これは、ロギングパラメータを変更する場合にも当てはまります。
DBAは多くの場合、postgresql.confファイルの複数のコピーを作成します。各コピーには、それぞれ異なる目的のために、わずかに異なるパラメーターがあります。さまざまな構成ファイルを手動で管理することは、エラーが発生しにくい場合は面倒な作業です。一方、構成管理システムでは、渡されたパラメーターに基づいて、postgresql.confファイルの名前を変更して異なるバージョンを使用することができます。このパラメーターは、現在のバージョンの目的を決定します。必要が完了したら、同じ入力パラメーターを変更することで、古い構成ファイルを元に戻すことができます。
たとえば、PostgreSQLインスタンスで実行されているすべてのステートメントをログに記録する場合は、パラメーター値が「log_statement=all」の構成ファイルを使用できます。すべてのステートメントを記録する必要がない場合(おそらくトラブルシューティングの演習の後)、以前の構成ファイルを復元できます。
PostgreSQLに個別のログファイルを使用する
通常の操作中にPostgreSQLのネイティブロギングコレクターを有効にすることをお勧めします。 PostgreSQLネイティブロギングを有効にするには、次のパラメータをonに設定します。
logging_collector = on
それには2つの理由があります:
まず、ビジー状態のシステムでは、オペレーティングシステムがPostgreSQLメッセージをsyslogに一貫して記録せず(nixベースのインストールを想定)、メッセージをドロップすることがよくあります。ネイティブPostgreSQLロギングでは、別のデーモンがイベントの記録を処理します。 PostgreSQLがビジー状態の場合、このプロセスはログファイルへの書き込みを延期し、クエリスレッドを終了させます。これにより、ログイベントが書き込まれるまでシステム全体がブロックされる可能性があります。したがって、(後で説明するように)あまり詳細でないメッセージをログに記録し、短縮されたログ行プレフィックスを使用すると便利です。
次に、後で説明するように、ログはログ管理ユーティリティを使用して収集、解析、インデックス作成、および分析する必要があります。 PostgreSQLにそのイベントをsyslogに記録させるということは、すべての「ノイズメッセージ」を除外するために、ログ管理部分にフィルタリングとパターンマッチングの追加レイヤーを作成することを意味します。専用のログファイルは、ほとんどのツールで簡単に解析してイベントのインデックスを作成できます。
ログの宛先をstderrに設定
「log_destination」パラメータについて考えてみましょう。 4つの値を持つことができます:
log_destination = stderr | syslog | csv | eventlog
ログイベントをコンマ区切り形式で保存する、またはWindowsでイベントログを保存する正当な理由がない限り、このパラメーターをstderrに設定することをお勧めします。これは、CSVファイルの宛先では、カスタムの「log_line_prefix」パラメーター値は効果がないにもかかわらず、プレフィックスに貴重な情報を含めることができるためです。
逆に、CSVログはデータベーステーブルに簡単にインポートでき、後で標準SQLを使用してクエリを実行できます。一部のPostgreSQLユーザーは、生のログファイルを処理するよりも便利だと感じています。後で説明するように、最新のログ管理ソリューションはPostgreSQLログをネイティブに解析し、それらから意味のある洞察を自動的に作成できます。 CSVを使用する場合、レポートと視覚化はユーザーが手動で行う必要があります。
最終的にそれはあなたの選択に帰着します。独自のデータ取り込みパイプラインを作成してCSVログをデータベーステーブルに読み込み、データをクレンジングして変換し、ビジネスニーズに合ったカスタムレポートを作成することに慣れている場合は、「log_destination」がCSVに設定されていることを確認してください。
>意味のあるログファイル名を使用する
PostgreSQLログファイルがローカルに保存されている場合、命名スタイルに従う必要はないように思われるかもしれません。非CSV形式のログの場合、デフォルトのファイル名スタイルは「postgresql-%Y-%m-%d_%H%M%S.log」です。これはほとんどの場合で十分です。
複数のサーバーから専用のログサーバー、マウントされたNFSボリューム、S3バケットなどの中央の場所にログファイルを保存する場合は、名前を付けることが重要になります。このような場合は、次の2つのパラメータを使用することをお勧めします。
log_directory log_filename
複数のインスタンスのログファイルを1つの場所に保存するには、まず、インスタンスごとに個別のディレクトリ階層を作成します。これは次のようになります。
/<Application_Name>/<Environment_Name>/<Instance_Name>
各PostgreSQLインスタンスの「log_directory」は、指定されたフォルダを指すことができます。
その後、各インスタンスは同じ「log_filename」パラメーター値を使用できます。デフォルト値では、
のようなファイルが作成されますpostgresql_2020-08-25_2359.log
より意味のある名前を使用するには、「log_filename」を次のように設定します。
log_filename = "postgresql_%A-%d-%B_%H%M"
ログファイルには次のような名前が付けられます:
postgresql_Saturday-23-August_2230
意味のあるログ行プレフィックスを使用する
PostgreSQLのログ行プレフィックスには、実際のメッセージ自体に加えて、最も価値のある情報を含めることができます。 Postgresのドキュメントには、ログイベントプレフィックス構成のいくつかのエスケープ文字が示されています。これらのエスケープシーケンスは、実行時にさまざまなステータス値に置き換えられます。 pgBadgerのような一部のアプリケーションは、特定のログ行プレフィックスを必要とします。
プレフィックスに次の情報を含めることをお勧めします:
- イベントの時間(ミリ秒なし):%t
- リモートクライアント名またはIPアドレス:%h
- ユーザー名:%u
- アクセスされたデータベース:%d
- アプリケーション名:%a
- プロセスID:%p
- 非セッションプロセス出力の終了:%q
- 各セッションまたはプロセスのログ行番号。1:%lから始まります
プレフィックスの各フィールドが何であるかを理解するために、フィールドの前に小さなリテラル文字列を追加できます。したがって、プロセスID値の前にリテラル「PID =」を付けることができ、データベース名の前に「db=」などを付けることができます。例を次に示します。
log_line_prefix = 'time=%t, pid=%p %q db=%d, usr=%u, client=%h , app=%a, line=%l '
イベントの発生元に応じて、ログ行のプレフィックスには異なる値が表示されます。バックグラウンドプロセスとユーザープロセスの両方が、メッセージをログファイルに記録します。システムプロセスには、%qを指定しました。これにより、プロセスID(%p)の後のテキストが抑制されます。その他のセッションでは、データベース名、ユーザー名、クライアントアドレス、アプリケーション名、および各イベントの番号付きの行が表示されます。
また、ログ行のプレフィックスの後にスペースを1つ含めました。このスペースは、ログイベントプレフィックスを実際のイベントメッセージから分離します。スペース文字である必要はありません。二重コロン(::)、ハイフン(-)、または別の意味のある区切り文字などを使用できます。
また、「log_hostname」パラメータを1に設定します:
log_hostname = 1
これがないと、クライアントのIPアドレスのみが表示されます。本番システムでは、これは通常、プロキシ、ロードバランサー、または接続プールのアドレスになります。これらのシステムのIPアドレスを心から知らない限り、それらのホスト名をログに記録する価値があるかもしれません。ただし、DNSルックアップにより、ロギングデーモンがファイルに書き込むための時間が余分に追加されます。
「log_line_prefix」と一緒に設定する必要があるもう1つのパラメーターは、「log_timezone」です。これをサーバーのローカルタイムゾーンに設定すると、ログに記録されたイベントを最初にローカル時間に変換するのではなく、タイムスタンプから簡単に追跡できるようになります。以下のコードスニペットでは、log_timzeoneをAustralian EasternStandardTimezoneに設定しています。
log_timezone = 'Australia/Sydney'
ログ接続のみ
2つのパラメータは、PostgreSQLがクライアントの接続と切断を記録する方法を制御します。デフォルトでは、両方のパラメーターがオフになっています。組織のセキュリティ要件に基づいて、これらの1つを1に設定し、もう1つを0に設定することをお勧めします(pgBadgerなどのツールを使用している場合を除く)。
log_connections = 1 log_disconnections = 0
log_connectionsを1に設定すると、許可されたすべての接続と試行されたが記録されます。 接続。これは明らかにセキュリティ監査に適しています。ブルートフォース攻撃はログから簡単に識別できます。ただし、この設定を有効にすると、数千、または数百の短期間の有効な接続があるビジーなPostgreSQL環境で、ログファイルが氾濫する可能性があります。
それでも、他の方法では明らかではない可能性のあるアプリケーションの問題を特定することもできます。多くの異なる有効なクライアントアドレスからの多数の接続試行は、インスタンスの前にロードバランサーまたは接続プールサービスが必要であることを示している可能性があります。単一のクライアントアドレスからの多数の接続試行により、ある種のスロットルを必要とするスレッドが多すぎるアプリケーションが発見される可能性があります。
ログDDLおよびDML操作のみ
Postgresログに何を記録する必要があるか、つまり「log_statement」パラメーターの値をどうするかについては、多くの議論があります。次の3つの値をとることができます:
log_statement = 'off' | 'ddl' | 'mod' | 'all'
サーバー上で実行されているすべてのSQLステートメントをキャプチャするためにこれを「すべて」に設定したくなるかもしれませんが、これは実際には必ずしも良い考えではないかもしれません。
ビジーな本番システムは、ほとんどの場合SELECTステートメントを実行し、1時間あたり数千のステートメントを実行することもあります。インスタンスは、パフォーマンスの問題なしに完全に正常に実行されている可能性があります。このような場合、このパラメータを「all」に設定すると、ログデーモンはこれらすべてのステートメントをファイルに書き込む必要があるため、不必要に負荷がかかります。
ただし、キャプチャしたいのは、データの破損、または何らかの問題を引き起こしたデータベース構造の変更です。不要または無許可のデータベース変更は、データの選択よりも多くのアプリケーションの問題を引き起こします。そのため、このパラメータを「mod」に設定することをお勧めします。この設定では、PostgreSQLはすべてのDDLおよびDMLの変更をログファイルに記録します。
PostgreSQLインスタンスが適度にビジー状態(1時間あたり数十のクエリ)の場合は、このパラメーターを「すべて」に設定してください。実行速度の遅いSELECTクエリのトラブルシューティングを行っている場合、または不正なデータアクセスを探している場合は、これを一時的に「すべて」に設定することもできます。 pgBadgerなどの一部のアプリケーションでも、これを「すべて」に設定する必要があります。
「警告」メッセージとアップをログに記録する
「log_statement」パラメーターが記録されるステートメントのタイプを決定する場合、次の2つのパラメーターがメッセージの詳細度を決定します。
log_min_messages log_min_error_statement
各PostgreSQLイベントには、関連付けられたメッセージレベルがあります。メッセージレベルは、冗長なDEBUGから簡潔なPANICまで何でもかまいません。レベルが低いほど、メッセージはより冗長になります。 「log_min_messages」パラメーターのデフォルト値は「WARNING」です。情報メッセージもログに記録する必要がない限り、このレベルに維持することをお勧めします。
「log_min_error_statement」パラメーターは、エラーをスローするSQLステートメントをログに記録するかどうかを制御します。 「log_min_message」と同様に、「log_min_error_statement」で指定された値以上のエラー重大度レベルを持つSQLステートメントが記録されます。デフォルト値は「ERROR」です。デフォルトのままにしておくことをお勧めします。
ログ期間パラメータをデフォルトのままにする
次に、次の2つのパラメータがあります。
log_duration log_min_duration_statement
「log_duration」パラメーターはブール値を取ります。 1に設定すると、完了したすべてのステートメントの期間がログに記録されます。 0に設定すると、ステートメント期間はログに記録されません。これはデフォルト値であり、パフォーマンスの問題をトラブルシューティングする場合を除いて、0のままにしておくことをお勧めします。ステートメントの期間を計算して記録すると、データベースエンジンは(どんなに小さくても)余分な作業を行うことになり、数百または数千のクエリに外挿すると、大幅な節約になる可能性があります。
最後に、「log_min_duration_statement」パラメーターがあります。このパラメーターが設定されている場合(単位なしの場合、ミリ秒と見なされます)、パラメーター値以上のステートメントの期間がログに記録されます。このパラメーター値を0に設定すると、完了したすべてのステートメントの期間が記録されます。これを-1に設定すると、ステートメント期間のログが無効になります。これはデフォルト値であり、そのままにしておくことをお勧めします。
このパラメーターを0に設定するのは、頻繁に実行されるクエリのパフォーマンスベースラインを作成する場合のみです。ただし、パラメータ「log_statement」が設定されている場合、ログに記録されるステートメントは、期間を示すログメッセージで繰り返されないことに注意してください。そのため、データベーステーブルにログファイルをロードしてから、ログ行のプレフィックスからプロセスIDとセッションIDの値を結合して、関連するステートメントとその期間を特定する必要があります。
手段が何であれ、頻繁に実行される各クエリのベースラインを取得したら、「log_min_duration_statement」パラメータをベースライン値の最大値に設定できます。これで、最大ベースライン値より長く実行されるクエリが微調整の候補になります。
エラーメッセージの詳細度をデフォルトに保つ
「log_error_verbosity」パラメーターには、次の3つの値を指定できます。
log_error_verbosity = terse | standard | verbose
このパラメータは、ログファイルに記録される各イベントについてPostgreSQLが記録する情報の量を制御します。データベースアプリケーションをデバッグしない限り、このパラメータは「デフォルト」のままにしておくのが最適です。詳細モードは、エラーを生成したファイル名または関数名とその行番号をキャプチャする必要がある場合に役立ちます。これを「簡潔」に設定すると、クエリのログ記録が抑制されますが、これも役に立たない可能性があります。
あなたのに有効なログローテーションポリシーを見つける ユースケース
ログファイルのサイズまたは経過時間のいずれかに基づいてログローテーションポリシーを作成することをお勧めしますが、両方ではありません。 2つのPostgreSQL構成パラメーターは、古いログがアーカイブされ、新しいログが作成される方法を指示します。
log_rotation_age = <number of minutes> log_rotation_size = <number of kilobytes>
「log_rotration_age」のデフォルト値は24時間で、「log_rotation_size」のデフォルト値は10メガバイトです。
ほとんどの場合、サイズローテーションポリシーを設定しても、アーカイブログファイルの最後のログメッセージがそのファイルにのみ完全に含まれるとは限りません。
「log_rotation_age」をデフォルト値の24時間に維持すると、各ファイルには1日分のイベントが含まれるため、各ファイルを簡単に識別して個別に調べることができます。ただし、これも、各ファイルが過去24時間のログの自己完結型の単位になることを保証するものではありません。パフォーマンスの遅いクエリが完了するまでに24時間以上かかる場合があります。古いファイルが閉じられ、新しいファイルが生成されたときにイベントが発生している可能性があります。これは、夜間のバッチジョブ中に発生する可能性があり、クエリの一部が1つのファイルに記録され、残りが別のファイルに記録されます。
あなたのに適したログローテーション期間を見つけることをお勧めします 使用事例。最も活動が少ない2つの連続する期間の間(たとえば、ある土曜日から次の土曜日まで)の時間差を確認します。次に、「log_rotation_age」値をその時間差に設定し、それらの期間の1つで、PostgreSQLサービスを再起動できます。そうすれば、PostgreSQLは、次の一時停止期間が発生したときに現在のログファイルをローテーションします。ただし、これらの期間の間にサービスを再起動する必要がある場合は、ログローテーションが再び歪められます。その後、このプロセスを繰り返す必要があります。しかし、PostgreSQLの他の多くのものと同様に、試行錯誤が最良の値を決定します。また、ログ管理ユーティリティを使用している場合は、ログマネージャーエージェントが追加されたファイルから各イベントを取り込むため、ログローテーションの経過時間やサイズは関係ありません。
pgBadgerなどのツールを使用する
pgBadgerは、Postgresログファイルから非常に有用な洞察を作成できる強力なPostgreSQLログアナライザです。これは、Perlで記述されたオープンソースのツールであり、実行するマシンのフットプリントは非常に小さくなっています。ツールはコマンドラインから実行され、多数のオプションが付属しています。入力として1つ以上のログを取り、以下に関する詳細な統計を含むHTMLレポートを生成できます。
- 最も頻繁に待機しているクエリ。
- ほとんどの一時ファイルまたは最大の一時ファイルを生成するクエリ
- 実行速度が最も遅いクエリ
- 平均クエリ期間
- 最も頻繁にクエリを実行する
- クエリで最も頻繁に発生するエラー
- クエリを実行するユーザーとアプリケーション
- チェックポイントの統計。
- 統計の自動真空化と自動分析。
- 統計のロック
- エラーイベント(パニック、致命的、エラー、警告)。
- 接続およびセッションプロファイル(データベース、ユーザー、アプリケーション別)
- セッションプロファイル
- クエリプロファイル(クエリタイプ、データベース/アプリケーションによるクエリ)
- I/O統計
- など
前述したように、pgBadgerがこれらのログを効果的に分析できるように、すべてのログイベントをキャプチャするには、ログ関連の構成パラメーターの一部を有効にする必要があります。これにより、多くのイベントを含む大きなログファイルが生成される可能性があるため、pgBadgerは、ベンチマークの作成またはパフォーマンスの問題のトラブルシューティングにのみ使用する必要があります。詳細なログが生成されたら、構成パラメーターを元の値に戻すことができます。継続的なログ分析には、専用のログ管理アプリケーションを使用するのが最適です。
コマンドプロンプトで操作したり、システムビューを使用したりすることに慣れている場合は、pg_stat_statementsを使用することをお勧めします。実際、これはすべての実稼働PostgreSQLインストールで有効にする必要があります。
pg_stat_statementsはPostgreSQLの拡張機能であり、現在デフォルトでインストールされています。これを有効にするには、「shared_preload_libraries」構成パラメーターの値の1つとしてpg_stat_statementsが必要です。その後、「CREATE EXTENSION」コマンドを使用して、他の拡張機能と同じようにインストールできます。拡張機能は、貴重なクエリ関連情報を提供するpg_stat_statementビューを作成します。
ログ管理アプリケーションを使用して洞察を得る
市場には多くのログ管理ユーティリティがあり、ほとんどの組織は最近1つ以上を使用しています。どのようなツールを使用していても、PostgreSQLログの収集と管理にそれを利用することをお勧めします。
それにはいくつかの理由があります:
自動化されたツールを使用すると、ログファイルからノイズを解析、分析、および除外する方がはるかに簡単です。場合によっては、イベントの期間、およびログローテーションの経過時間またはサイズに基づいて、イベントが複数のログファイルにまたがることがあります。ログマネージャーを使用すると、この情報を全体として表示するのがはるかに簡単になります。
今日のログ管理ソリューションには、通常、PostgreSQLログを解析する機能が組み込まれています。一部には、これらのログから抽出された最も一般的なメトリックを表示できるダッシュボードも付属しています。
最新のログ管理アプリケーションのほとんどは、強力な検索、フィルター、パターンマッチング、イベント相関、およびAI対応の傾向分析機能も提供します。これらのツールを使用すると、通常の目には見えないものを簡単に明らかにすることができます。
最後に、ログマネージャーを使用してPostgreSQLログを保存すると、元のファイルが誤ってまたは悪意を持って削除された場合でも、イベントは後世のために保存されます。
ログ管理アプリケーションを使用することには明らかな利点がありますが、多くの組織には場所に関する制限があります。 彼らのログは生きることができます。これは、ログが組織の地理的境界の外に保存されることが多いSaaSベースのソリューションの典型的なケースであり、規制要件に準拠していない可能性があります。
このような場合は、可能であれば、ローカルデータセンターが存在するベンダーを選択するか、ELKスタックなどの組織のネットワークでホストされている自己管理型ログマネージャーを使用することをお勧めします。
最後の言葉
PostgreSQLサーバーログは、適切に構成されている場合、情報の宝庫になる可能性があります。秘訣は、何をログに記録するか、どれだけログを記録するかを決定することです。さらに重要なことは、ログが必要なときに適切な情報を提供できるかどうかをテストすることです。試行錯誤の問題ですが、今日ここで説明したことは、かなりまともなスタートを切るはずです。冒頭で述べたように、最適な結果を得るためにPostgreSQLログを構成した経験について聞いてうれしく思います。