Amazon Web Services ブログ
RDS および Aurora PostgreSQL ログの操作: パート 1
PostgreSQL は最も人気のあるオープンソースのリレーショナルデータベースシステムの 1 つです。30 年以上におよぶ開発作業を経ている PostgreSQL は、多数の複雑なデータワークロードを処理できる、信頼性が高く堅牢なデータベースであることが証明されています。AWS は 2 つのマネージド型 PostgreSQL オプションを提供しています。Amazon RDS for PostgreSQL と Amazon Aurora PostgreSQL です。デバッグやモニタリングのためのデータベースアクティビティログをどのようにキャプチャするのかという質問が、新規の PostgreSQL ユーザーから多く寄せられます。この記事では、RDS および Aurora PostgreSQL を設定して追加のエンジンログを生成する方法について説明します。記事の第 2 部である RDS および Aurora PostgreSQL ログの操作: パート 2 では、これらのログファイルにアクセスする方法をご紹介します。
PostgreSQL は、データベース管理者 (DBA) に役立つ情報を含むイベントログを生成します。デフォルトでは、SQL クエリエラー、ログイン試行の失敗、デッドロックがデータベースログにキャプチャされます。これらのエラーメッセージはアプリケーションのさまざまな問題の特定に役立ちます。たとえば、レガシーアプリケーションを Oracle から PostgreSQL に変換すると、一部のクエリが PostgreSQL 構文に正しく変換されないことがあります。こうした誤った形式のクエリによってログにエラーメッセージが生成されるため、問題のあるアプリケーションコードを特定するのに役立ちます。
デフォルトのログ記録を使用するだけでなく、PostgreSQL ログ記録パラメータに変更を加えれば、パフォーマンスの低下やセキュリティ監査などの問題を特定、解決するのに役立つ情報を取得できます。このログ記録パラメータを設定すると、接続と切断、スキーマ変更クエリ、すべてのスロークエリとその時間、ロックのため待機中で時間がかかるクエリ、一時的なディスクストレージを消費するクエリ、リソースを消費するバックエンド自動バキュームプロセスなどの情報をキャプチャできます。
このログ情報は、データベース使用中の潜在的なパフォーマンスと監査の問題をトラブルシューティングするのに有用です。この記事では、このログ記録の有効化とその利点について詳しく説明します。
DB パラメータグループ
RDS および Aurora PostgreSQL の各インスタンスは、エンジン固有の設定を含むパラメータグループと関連付いています。エンジンの設定には、PostgreSQL のログ記録動作を制御するパラメータもいくつか含まれています。AWS では、インスタンスで使用できるよう、デフォルト設定のパラメータグループを提供しています。ただし、デフォルトの設定を変更するには、デフォルトのパラメータグループのクローンを作成し、そのクローンを要件に従って変更して、RDS または Aurora PostgreSQL インスタンスにアタッチする必要があります。
パラメータグループについての詳細や、インスタンスのカスタムパラメータグループを作成する手順についての詳細は、RDS ユーザーガイドの「DB パラメータグループを使用する」を参照してください。
PostgreSQL のログファイル
ログファイルには、RDS および Aurora PostgreSQL インスタンスによって生成されるエンジンログが保存されています。PostgreSQL では、ログファイルの命名規則とローテーションポリシーを選択する際にいくつかのパラメータを利用できます。このパラメータにより、周期的、もしくは固定的な最大サイズのログファイルを生成できます。
パラメータ log_filename
では、ログファイルの名前を指定します。Aurora PostgreSQL 9.6 および RDS PostgreSQL では、次の 2 つのファイル命名オプションを使用できます。
-
postgresql.log.%Y-%m-%d
– このオプションでは、1 日ごとに一意のログファイル名を使用します。例えば、postgresql.log.2019-04-01
といった具合です。 -
postgresql.log.%Y-%m-%d-%H
– このオプションでは、1 時間ごとに一意のログファイル名を使用します。例えば、postgresql.log.2019-04-01-12
といった具合です。
Aurora PostgreSQL 10 では、postgresql.log.%Y-%m-%d-%H%M
というログファイル名オプションが追加されました。このオプションでは、分単位で一意のログファイル名を使用できます。たとえば、午後 12 時 30 分に開始する場合、新規ログファイルの名前は postgresql.log.2019-04-01-1230
となります。
PostgreSQL は、パラメータ log_rotation_age
または log_rotation_size
で指定された条件を満たすと、新規ログファイルを作成して使用し始めます。パラメータ log_rotation_age
では、ログファイルの最大期間 (分単位) を指定します。この期間が過ぎた後、PostgreSQL はファイル命名規則を使用して新規ログファイルを生成します。同様に、パラメータ log_rotation_size
では、ログファイルの最大サイズ (KB 単位) を指定します。ログファイルがこのサイズに達すると、PostgreSQL はファイル命名規則を使用して新規ログファイルを生成します。
RDS および Aurora PostgreSQL は、既存のログファイルに上書きすることはありません。たとえば、日次のログ命名規則 (postgresql.log.%Y-%m-%d
) を使用しており、log_rotation_size
が 1 MB であるとします。この例では、ファイルが 1MB に達し、日付が変わらない場合、PostgreSQL はファイルを切り捨てずに同じファイルに書き込みを続けます。パラメータ log_truncate_on_rotation
は RDS および Aurora PostgreSQL では false にハードコードされており、この動作を制御します。
PostgreSQL ログの出力形式
デフォルトでは、RDS および Aurora PostgreSQL は標準エラー (stderr) 形式でログを生成します。この形式では、各ログメッセージにはパラメータ log_line_prefix
で指定された情報のプレフィックスが付けられます。RDS や Aurora でこのパラメータに使用できるのは、以下の値のみです。
この値は以下のコードにマッピングされます。
このプレフィックスは便利ですが、comma-separated-values (CSV) 形式のログ出力を有効にするとさらに詳細なログメッセージを取得できる場合があります。
パラメータ log_destination
は、インスタンスが出力ログを生成する形式を制御します。CSV 形式のログ出力を有効にするには、インスタンスに関連付いている DB パラメータグループ内でパラメータ log_destination
を csvlog
に設定します。この変更により、RDS および Aurora PostgreSQL エンジンがトリガーされ、標準出力ファイルに加えて CSV 出力ファイルが生成されます。
CSV 形式は log_fdw
拡張機能を使用する際に特に便利です。詳細については、この記事のパート 2 をご覧ください。
デフォルトのログ記録
デフォルトでは、RDS および Aurora PostgreSQL のログ記録パラメータは、クエリエラー、ログインの失敗、致命的なサーバーエラー、デッドロックなどのサーバーエラーをすべてキャプチャするよう設定されています。このデフォルトのログ記録レベルは、サーバーに影響を与えるあらゆるエラーをキャプチャするのに不可欠です。
たとえば、無効な列名でクエリを実行すると、ユーザーは次のログメッセージを取得します。
標準エラー形式
CSV 形式
これらのエラーメッセージは、しばしば誤った形式のクエリや見つからないオブジェクトの特定に役立ちます。たとえば、Oracle から PostgreSQL に変換するときに、関数を 1 つ見逃したかもしれないとします。クエリがこの関数を呼び出そうとすると、関数が見つからないというエラーメッセージが表示され、呼び出しが失敗します。このメッセージにより、DBA は失敗の原因を特定し、迅速に修正することができます。
ユーザー認証が失敗すると、ユーザーは次のログメッセージを取得します。
標準エラー形式
CSV 形式
この情報はセキュリティ面で価値があります。この情報を見た DBA は、ログイン試行の失敗が複数回検出された場合にそのユーザーのロックアウトを決定できます。エラーメッセージはまた、無効な接続リクエストの送信元サーバーを DBA が絞り込むのに役立つソース IP アドレスも提供します。
このデフォルトのログ記録に加えて、追加のログ記録パラメータを設定すると、サーバーアクティビティの詳細をさらに取得することができます。次のセクションでは、DBA にとって役立つ、主要なログ記録パラメータについて説明します。
ログ記録パラメータの設定
PostgreSQL ユーザーは、エンジンパラメータをチューニングすることで追加のログ記録を有効にすることができます。このセクションでは、エンジンアクティビティログをより多くキャプチャするために設定できる主要なパラメータをいくつか説明します。追加のログ記録パラメータの詳細については、PostgreSQL ドキュメントの「Error Reporting and Logging」セクションを参照してください。
データベースログ記録を増やすと、ストレージサイズ、I/O 使用量、および CPU 使用量に影響が出ます。そのため、本番環境にデプロイする前にこれらの変更をテストしてください。
rds.log_retention_period
このパラメータは、RDS および Aurora PostgreSQL のエンジンログファイルの保持期間 (分単位) を指定します。デフォルトでは、ログは 4320 分 (3 日) 間保持されます。このパラメータに使用できる最大値は 10080 分 (7 日) です。この最大値以上にログを保持する必要がある場合は、このデフォルトの場所から移動させなければなりません。この記事のパート 2 では、ログファイルをエクスポートする方法について説明します。
log_connections
デフォルトでは、新規接続の詳細はログに記録されません。新規クライアント接続の詳細をすべて記録するには、このパラメータを 1 に設定します。以下の出力は、新規クライアント接続のログのサンプルです。
標準エラー形式
CSV 形式
接続ログは、接続のソース、ユーザー名、頻度、時間を判断するのに役立ちます。この情報は、アクティビティのトラブルシューティングまたはセキュリティ監査に有用な場合があります。このログ記録を有効にすると、1 日に受け入れる新規接続数、各ホストまたは各ユーザーからの接続数、またはすべての接続に SSL が使用されているかどうか、といった疑問に答えることができます。
通常、接続ログ記録は有効にしておくことをお勧めします。アプリケーションは接続プーラーを頻繁に使用するため、接続が開かれるのは 1 回で、長時間開かれたままになります。開かれた新規接続数が少ないほど、ログファイルにキャプチャされる接続ログメッセージも少なくなります。
log_disconnections
デフォルトでは、切断の詳細は記録されません。クライアント切断をすべて記録するには、このパラメータを 1 に設定します。以下の出力は、クライアント切断のログのサンプルです。
標準エラー形式
CSV 形式
切断情報を確認すると、ユーザーがデータベースに接続していた時間を正確に判断できます。この情報は監査で有用です。通常、切断ログ記録は有効にしておくことをお勧めします。
log_temp_files
許可されたメモリ (work_mem
) を使用してオペレーションを完了することができない場合、クエリはディスク上の一時ファイルを使用します。こうしたオペレーションには、ソート、ハッシュ、および一時的なクエリの結果の保存も含まれます。ディスクアクセスのパフォーマンスはメモリアクセスよりもはるかに遅くなるため、クエリで一時ファイルを使用する必要がある場合は必ずパフォーマンスに影響が出ます。このため、一時ファイル使用ログ記録を有効にすることが重要です。このログ記録を有効にするには、log_temp_files
パラメータを 0 に設定 (して、すべての一時ファイルを記録) するか、または任意の正数 (デフォルトでは KB 単位) に設定します。この正数は、超えた場合にログに記録される一時ファイルサイズのしきい値を指定するものです。
たとえば、クエリが log_temp_files
で指定されたしきい値サイズ以上の一時ファイルを使用すると、ユーザーは次のログメッセージを取得します。
標準エラー形式
CSV 形式
このログメッセージはクエリが生成する一時ファイルのサイズを示しています。この情報に基づき、可能であれば work_mem
を増やしたり、クエリをチューニングしたりすると、一時ファイルの使用を最小限に抑えることができます。
log_lock_waits
このパラメータを 1 に設定すると、デッドロックの検出に設定された期間 (デフォルトでは 1 秒) よりも長い期間ロック状態のままのログ記録セッションが有効になります。この情報は、セッションのロックがパフォーマンスの問題を引き起こしているかどうかを判断する際に役立ちます。
たとえば、あるトランザクションが別のトランザクションをブロックすると、ユーザーは次のログメッセージを取得します。
標準エラー形式
CSV 形式
このログメッセージはロックのために待機中のクエリを示しており、これによりブロッキングセッションの PID も分かります。この情報は、パフォーマンスの問題のデバッグに役立ちます。この情報を使用して互いにブロックし合っているトランザクションを特定し最適化することで、ロックを回避または削減することができます。たとえば、同じ行の更新を試行する 2 つのトランザクションは互いにロックし合います。このエラーメッセージは、これらのトランザクションを分離するのに役立ち、トランザクションの改善につながります。
log_autovacuum_min_duration
自動バキュームデーモンプロセスは、設定通りにバックグラウンドで実行され、データベースにおける肥大化の進行を防ぎます。この機能は重要ですが、CPU、メモリ、および IO リソースの使用量が増えます。パラメータ log_autovacuum_min_duration
により、このバックグラウンドプロセスがいつどのテーブルで実行されるか把握できるようになります。このパラメータを 0 に設定すると、すべての自動バキュームおよび自動分析の実行の情報が記録され始めます。パラメータを任意の正の値 (ミリ秒単位) に設定すると、設定した値以上の時間がかかる自動バキュームおよび自動分析の実行のみのログが作成されます。
たとえば、このパラメータと rds.force_autovacuum_logging_level
(次のセクションで説明) を log に設定すると、その後でユーザーは自動バキュームと自動分析の実行に関する次のログメッセージを取得します。
標準エラー形式
CSV 形式
これは、自動バキュームが実行された時間、完了に要した時間、そして行ったクリーンアップの情報を含んだログメッセージです。この情報は、高い I/O やピーク時の CPU 負荷、自動バキュームがロックされて古い行を処理できないため進行しているテーブルの肥大化など、パフォーマンス問題の調査を行う際に役立ちます。
rds.force_autovacuum_logging_level
RDS および Aurora PostgreSQL では、自動バキュームと自動分析プロセスのログ記録がデフォルトで無効になっています。自動バキュームのログ記録パラメータである log_autovacuum_min_duration
は、希望する値に変更しない限り動作しません。このパラメータに使用できる値は、disabled
、debug5
、debug4
、debug3
、debug2
、debug1
、info
、notice
、warning
、error
、log
、fatal
、panic
です。
このパラメータに、disabled 以外の値 (log など) を設定すると、PostgreSQL エンジンがパラメータ log_autovacuum_min_duration で設定されたしきい値のとおりに自動バキュームおよび自動分析アクティビティのログ記録を開始します。
log_min_duration_statement
このパラメータは、スロークエリのログ記録を可能にする貴重な機能を提供してくれます。-1 (つまり無効) 以外の値 (ミリ秒単位) が設定されると、データベースが全クエリのログ記録を開始します。これには最低でも指定したミリ秒単位の時間がかかります。
例えば、クエリが log_min_duration_statement
で指定されたしきい値以上の時間を要する場合、ユーザーは次のログメッセージを取得します。
標準エラー形式
CSV 形式
ログメッセージでは、クエリの所要時間に加え、誰がどのソース IP からいつクエリを実行したかについても情報が提供されます。この情報はクエリのソースを識別し、次のステップを決定するうえで役立ちます。
このパラメータは多くのシナリオで有用です。例えば、全クエリが 1 秒以内に完了すると見込まれている場合、このパラメータを 1 秒に設定することで、これより時間のかかるクエリをキャプチャすることができます。また、クエリパフォーマンス向上タスクに取り掛かるときには、まず一番遅いクエリから重点的に取り組みたいことでしょう。これは、このパラメータをカットオフ値に設定し、カットオフ時間より時間が掛かっている全クエリのキャプチャを開始することで可能です。それらのクエリすべての最適化が完了した後でこのパラメータをさらに下げると、次に遅いクエリのセットに取り掛かることができます。
log_statement
これも、クエリログ記録における便利な機能です。サポートされているパラメータ値は次のとおりです。
- “
none
” – この機能がオフになっています。 - “
ddl
” – 全 DDL ステートメントを記録します。 - “
mod
” – 全 INSERT、UPDATE、DELETE ステートメントを記録します。 - “
all
” – 全ステートメントを記録します。
監査目的でスキーマ変更関連の全ステートメントをキャプチャするには、このパラメータを ddl
に設定すると良いでしょう。
例えば、列をドロップすると次のログメッセージがキャプチャされます。
標準エラー形式
CSV 形式
rds.force_admin_logging_level
RDS および Aurora PostgreSQL には rdsadmin
という内部スーパーユーザーが存在します。このユーザーはデータベース管理アクティビティにのみ使用されます。例えば、マスターユーザー用のパスワードを忘れ、リセットしたいとします。この rdsadminuser
は AWS マネジメントコンソールからパスワードを変更する際にパスワードリセットを実行します。このユーザーのアクティビティは、上記のセクションで説明したパラメータの設定後であってもキャプチャされません。このユーザーからアクティビティをキャプチャする必要がある場合、rds.force_admin_logging_level
を log に設定して有効化します。このパラメータを設定すると、PostgreSQL エンジンによって、全ユーザーデータベースでこの管理ユーザーが実行する全クエリのキャプチャが開始されます。
ネイティブ以外のログ記録パラメータ
PostgreSQL は前のセクションで説明したネイティブパラメータに加え、外部プラグインもサポートしています。外部プラグインではイベントログ記録のレベルをさらに上げることができます。便利なログ記録情報を追加するプラグインとしては、pgAudit
と auto_explain
の 2 つがよく使われます。
pgAudit
pgAudit 拡張機能には、ネイティブログ記録パラメータが提供する基本的なステートメントログ記録機能をしのぐ有用性があります。監査に必要なセッションレベルまたはオブジェクトレベルの情報ログ記録には、この拡張機能を使います。例えば、機密情報を含むテーブルに対して実行される全クエリを記録する必要があるとします。PostgreSQL でネイティブに利用できる唯一のオプションは、log_statement
を all に設定するか、または log_min_duration_statement
を 0 に設定することでデータベース上で実行される全クエリをキャプチャすることです。これで希望するデータを取得できますが、不要なデータまでキャプチャしてしまいます。pgAudit
拡張機能は、どのオブジェクトに関して何をキャプチャするか選択できるようにすることで、このユースケースをサポートします。
Amazon RDS および Aurora PostgreSQL で pgAudit
を設定する方法の詳細については、RDS ユーザーガイドの「pgaudit 拡張機能の使用」をご覧ください。
例えば、テストテーブル logtest1
の監査を有効にすると、ユーザーは次のログメッセージを取得します。
標準エラー形式
CSV 形式
auto_explain
auto_explain
を使用すると、そのメカニズムにより、クエリが auto_explain.log_min_duration
パラメータで指定されたしきい値以上の時間を要するたびにクエリ実行計画が自動的に記録されるようになります。auto_explain
機能を有効化するには、データベースインスタンスと関連付けられたパラメータグループの shared_preload_libraries
パラメータに auto_explain
を追加します。auto_explain
設定についての詳細は、PostgreSQL ドキュメントの「auto_explain」をご覧ください。
例えば、テストクエリの実行時間が設定したしきい値を超えると、ユーザーは次のログメッセージを取得します。
標準エラー形式
CSV 形式
まとめ
この記事では、PostgreSQL ログファイルの重要さに焦点を当て、パフォーマンスチューニングやトラブルシューティングに役立つデータベースアクティビティ情報を追加で得られる、チューニング可能なパラメータのいくつかについて説明しました。これらのパラメータはご自身の要件に合わせて評価や設定をする必要があります。追加のログ記録を有効化するとサーバーの負荷が増えるため、本稼働環境でデプロイする前に設定変更のテストを行ってください。
この記事のパート 2 では、生成されたログファイルにアクセスしてこれを使用するためのさまざまな方法をご紹介します。
ご質問やご意見はコメント欄にお寄せください。
本稿の執筆者について
Yaser Raja は、アマゾン ウェブ サービスでプロフェッショナルサービスチームのシニアコンサルタントを務めています。お客様と協力し、AWS クラウドでスケーラブルかつ可用性と安全性に優れたソリューションの構築に取り組んでいます。専門分野は、オンプレミスデータベースの Amazon RDS および Aurora PostgreSQL への同種間移行および異種間移行です。