Amazon Web Services ブログ

RDS および Aurora PostgreSQL ログの操作: パート 2

このシリーズの最初の投稿である RDS および Aurora PostgreSQL ログの操作: パート 1 では、PostgreSQL のログの重要性と、より多くのデータベースアクティビティの詳細情報をキャプチャするためのさまざまなパラメータを調整する方法を記載しています。PostgreSQL ログは、データベースの問題を解決するのに役立つ情報を提供します。この投稿は、PostgreSQL ログにアクセスするためのさまざまな方法に焦点を当てています。

PostgreSQL ログはクラスターの各インスタンスに生成および保存されます。これらのログファイルにアクセスする方法は複数あります。以下のセクションでは、これらの方法をいくつか説明します。

AWS マネジメントコンソールにアクセスする

PostgreSQL ログファイルにアクセスするための最も直接的な方法は、AWS Management Console を介して行います。以下の手順を実行します。

  1. Amazon RDSを開きます。
  2. RDS/Aurora インスタンスを選択します。
  3. [ログとイベント] を選択します。
  4. [Logs] で必要なログファイルを選択します。
  5. [View]、[Watch]、または[Download]のいずれかを選択します。

以下のスクリーンショットは、[Logs] セクションのプレビューです。

これは、ログファイルを表示またはダウンロードするための最も基本的な方法です。

CloudWatch Logs にログファイルを発行する

RDS および Aurora PostgreSQL は、Amazon CloudWatch Logs へのログの発行をサポートしています。詳細については、RDS ユーザーガイドの「PostgreSQL ログの Amazon CloudWatch Logs への発行」を参照してください。

ログが CloudWatch Logs の場合、アラームを作成し、リアルタイム分析を行うことができます。たとえば、log_statementsddl に設定した場合、DDL ステートメントが実行されたときは常にアラートするアラームを設定できます。

CloudWatch Logs では、ログ分析に役立つオプションを検索およびフィルタリングできます。詳細については、「フィルターとパターンの構文」を参照してください

たとえば、以下のスクリーンショットは、FATAL または ERROR という語を含む最後の 5 分間に生成された PostgreSQL ログのメッセージを示しています。

AWS CLI を使用してログファイルをダウンロードする

AWS CLI を使用して RDS および Aurora PostgreSQL ログファイルをダウンロードできます。AWS CLI のコマンドを実行する前に、適切な IAM ロールを割り当てて、IAM ユーザー認証を設定し、または Amazon EC2 インスタンスを使用します。詳細については「AWS CLI のインストール」と「AWS CLI の設定」をご参照ください。

ログファイルをダウンロードするために使用された IAM ユーザーまたはロールは、rds:DescribeDBLogFiles および rds:DownloadDBLogFilePortion のオペレーションを実行する権限を有している必要があります。詳細については、「IAM 権限の管理」 を参照してください。

以下の AWS CLI コマンドは、所定のインスタンスで利用可能なログファイルをリストします。

$ aws rds describe-db-log-files --db-instance-identifier wxyzpgprod --output text
DESCRIBEDBLOGFILES      1552013774000   error/postgresql.log.2019-03-08-02      3912
DESCRIBEDBLOGFILES      1552017375000   error/postgresql.log.2019-03-08-03      3912
DESCRIBEDBLOGFILES      1552020975000   error/postgresql.log.2019-03-08-04      3912
…

以下のコマンドを用いて、このリストから必要なファイル名を選択し、必要なファイルをダウンロードできます。

$ aws rds download-db-log-file-portion --db-instance-identifier wxyzpgprod --output text --starting-token 0 --log-file-name error/postgresql.log.2019-03-08-02 > logfile.txt

スクリプトを用いて、所定の時間ウィンドウの間に生成されたログファイルをダウンロードする手順を自動化できます。サンプルのスクリプトについては、GitHub リポジトリの get_rds_log_files.sh を参照してください。スクリプトは、AWS CLI 認証を設定するための aws configure をすでに実行しているか、または PostgreSQL ログファイルのダウンロードを許可する割り当てられたロールで EC2 インスタンスから実行していることを想定しています。スクリプトは、RDS または Aurora PostgreSQL インスタンス名および日付範囲を引数として想定しており、所定の時間ウィンドウの間にそのインスタンスのために生成されたログファイルをダウンロードします。

デフォルトでは、このスクリプトは、デフォルトの標準形式 (stderr) ファイルをダウンロードします。CSV 形式のログファイルを使用している場合、「-c 1」の引数を使用してダウンロードできます。

日付範囲を指定しない場合、このスクリプトは、その日に生成されたすべてのログファイルをダウンロードします。

以下は、スクリプトのヘルプ出力です。

$ ./get_rds_log_files.sh -h
USAGE: ./get_rds_log_files.sh [OPTIONS]
Options:
    -r  : AWS Region.Default 'us-east-1'
    -d  : RDS PostgreSQL Instance Name.Default 'wxyzpgprod'
    -c  : Use CSV log files.Allowed values 0 or 1.Default '0'
    -s  : Start date of log file [YYYY-MM-DD or YYYY-MM-DD-HH].Defaults to current date (in UTC) '2019-02-06'
    -e  : End date of log file [YYYY-MM-DD or YYYY-MM-DD-HH].Defaults to next day (in UTC) '2019-02-07'

以下は、EC2 ジャンプサーバーからのスクリプトのサンプル出力です。

$ ./get_rds_log_files.sh -d wxyzpgprod -s '2019-02-06-16' -e '2019-02-06-18'

20190206-142134: Fetching logs generated between dates [ 2019-02-06-16 ] and [ 2019-02-06-18 ] (UTC).
20190206-142135: Downloading Logfile = postgresql.log.2019-02-06-16
20190206-142136: Downloading Logfile = postgresql.log.2019-02-06-17
20190206-142138: Downloading Logfile = postgresql.log.2019-02-06-18
20190206-142140: RDS Logs download completed.

$ ls postgresql.log.*
postgresql.log.2019-02-06-16  postgresql.log.2019-02-06-17  postgresql.log.2019-02-06-18

カスタムスクリプトまたは pgBadger などのPostgreSQL ログファイルの分析ツールを使用して、分析のためにログファイルをダウンロードする必要があります。

log_fdw を使用して外部テーブル経由でログデータを表示する

SQL インターフェイスを使用して PostgreSQL ログにアクセスするには、log_fdw の拡張を使用します。ログファイル上部に外部テーブルを作成し、SQL クエリで利用できます。外部テーブルは、この PostgreSQL サーバーの外部に存在するデータにアクセスするメカニズムを提供します。いくつかの手順を行うことで、必要なログファイルにリンクし、トラブルシューティングまたはモニタリングアクティビティを開始できます。詳細については、PostgreSQL の文書の「外部テーブル」をご覧ください。

CSV 形式は log_fdw 拡張を使用するのに便利です。stderr ログファイルに作成された外部テーブルは、ログイベントデータのある単一の列を含みます。CSV 形式のログファイルについては、外部テーブルに複数の列があり、分析を容易にしています。

以下のセクションは、この拡張の使用方法および単一の関数の呼出しで利用可能なログファイルを読み込むカスタム関数についての詳細を提供しています。

基本的な使用手順

log_fdw を設定し、使用するには、次の手順を実行します。

  1. psql または pgAdminなどのクライアントを使用して PostgreSQL データベースに接続します。
  2. 以下の SQL ステートメントを使用して log_fdw を作成します。
    CREATE EXTENSION log_fdw;
  3. 以下の SQL ステートメントとともに log_fdw を使用して外部サーバーを作成します。
    CREATE SERVER log_server FOREIGN DATA WRAPPER log_fdw;
  4. 以下の SQL ステートメントで最近のログファイルのリストを取得します。
    SELECT * FROM list_postgres_log_files() ORDER BY 1 DESC;

    以下のサンプル出力は、5 行に制限されます。

    log_test=> SELECT * FROM list_postgres_log_files() ORDER BY 1 DESC LIMIT 5;
                file_name             | file_size_bytes
    ----------------------------------+-----------------
     postgresql.log.2019-03-07-21     |          235909
     postgresql.log.2019-03-07-20     |         1008923
     postgresql.log.2019-03-07-19     |         1098235
     postgresql.log.2019-03-07-18     |         1019780
     postgresql.log.2019-03-07-17     |          970201
    (5 rows)

    CSV ログ形式を設定した場合、CSV 出力ファイルも生成します。直近の 5 つの CSV ログファイルのリストを取得するには、以下の SQL コードを使用します。

    SELECT * FROM list_postgres_log_files() WHERE file_name LIKE 'postgresql.log.%.csv' ORDER BY 1 DESC;

    以下のサンプル出力は、直近の 5 つのログファイルに制限されます。

    log_test=> SELECT * FROM list_postgres_log_files() WHERE file_name LIKE 'postgresql.log.%.csv' ORDER BY 1 DESC LIMIT 5;
                file_name             | file_size_bytes
    ----------------------------------+-----------------
     postgresql.log.2019-03-07-21.csv |          407902
     postgresql.log.2019-03-07-20.csv |         1267089
     postgresql.log.2019-03-07-19.csv |         1397837
     postgresql.log.2019-03-07-18.csv |         1281672
     postgresql.log.2019-03-07-17.csv |         1212340
    (5 rows)

    ログファイル名のタイムスタンプは、UTC タイムゾーンのものです。たとえば、postgresql.log.2019-03-07-21.csvのファイルは、午後 9 時 (UTC) 以降で、午後 10 時 (UTC) より前のタイムスタンプで 3 月 7 日に生成されたログを含みます。

  5. 以下の SQL ステートメントを使用して、外部テーブルとして、これらのファイルのいずれかを読み込みます。
    SELECT create_foreign_table_for_log_file('pglog_20190307_21', 'log_server', 'postgresql.log.2019-03-07-21.csv');

    この関数の最初の引数は、外部テーブルに付与することを希望する名前です。2 つ目の引数は、作成した外部サーバーの名前です。3 つ目の引数は、log_fdw を介して利用可能にすることを希望するログファイル名です。

  6. 先行するステートメントが正常に行われると、外部テーブルの分析が可能となります。以下のコードを使用します。
    SELECT * FROM pglog_20190307_21 ORDER BY 1;

    以下のサンプル出力クエリは、ログ数の行を取得します。現在アクティブなログファイルは、リアルタイムで新しいログの行を示すために続行します。

    log_test=> SELECT count(1) FROM pglog_20190307_21;
     count
    -------
      2311
    (1 row)
    log_test=> select count(1) from pglog_20190307_21;
     count
    -------
      2776
    (1 row)
  7. 外部テーブルを使用して完了したら、以下の SQL ステートメントを使用してドロップします。
    DROP FOREIGN TABLE pglog_20190307_21;

    デフォルトでは、テーブルは、デフォルトのスキーマで作成されます。特定のスキーマでテーブルを作成したい場合、search_path でスキーマを追加し、優先順位を高くします。次のコードをご覧ください。

    CREATE SCHEMA dba;
    SET search_path = dba, public;
    

    search_path を変更した後、create_foreign_table_for_log_file の関数により作成された外部テーブルは、dba スキーマで作成されます。

単一テーブルおしてログファイルを読み込む

ログファイルの数が少ない場合は、前の手順が有用です。分析のための外部テーブルを簡単に作成できます。しかし、すべての利用可能なログファイルを見る必要がある場合、個別に各ファイルを読み込むことは時間の無駄です。

この問題に対処するには、GitHub リポジトリで利用可能なload_postgres_log_files() のカスタム関数を使用します。この関数は、利用可能なログファイルを単一テーブルとして読み込むプロセスを簡素化します。以下の手順を実行します。

  1. GitHub リポジトリから load_postgres_log_files 関数の SQL ファイルをダウンロードします。
  2. load_postgres_log_files の関数を作成します。
  3. 以下のステートメントを実行して、ログファイルを読み込みます。
    SELECT public.load_postgres_log_files();
  4. 以下のコードのあるログを見ます。
    SELECT * FROM logs.postgres_logs;
  5. 必要に応じて、手順 2 を繰り返して、最後の読み込み以降に生成された新しいログファイルをピックアップします。
  6. ログ分析を完了したら、以下のコードでテーブルをドロップします。
    DROP TABLE logs.postgres_logs CASCADE;

以下は、この関数の主要な機能です。

  • デフォルトでは、postgres_logs と名付けられたテーブルがスキーマログで作成されます。
  • 引数を介してスキーマ名とテーブル名を変更できます。
  • 既存のテーブルはドロップされます。
  • スキーマログが存在しない場合、作成されます。
  • 各ログファイルは、外部テーブルとして読み込まれ、logs.postgres_logs のテーブルの子となります。
  • デフォルトでは、関数は、CSV ファイル形式のログを探します。CSV ファイルが見つからない場合、標準エラー形式のログファイルに戻ります。このふるまいを変更するには、v_prefer_csv の引数を false に設定します。
  • 以下の日、時間、分ベースのログファイル名形式は、CSV および 非 CSV 出力ファイルをサポートしています。
    • postgresql.log.YYYY-MM-DD
    • postgresql.log.YYYY-MM-DD-HH
    • postgresql.log.YYYY-MM-DD-HHMI
  • CSV 形式を使用することにより、各ログファイルについて作成された子テーブルにチェック制約が追加されます。

独自のスキーマおよびテーブル名を使用するには、以下のとおり手順 3 のコマンドを実行します。

SELECT public.load_postgres_log_files('myschema', 'mytable');

手動でリロードすることなく、最新のログが常にこのテーブルで利用可能な状態にしておく必要がある場合、1 時間ごとにこの関数を呼び出すための cron ジョブまたはスケジュールされた Lambda 関数を書き込むことができます。詳細については、「Rate または Cron を使用したスケジュール式」をご覧ください。

まとめ

RDS および Aurora PostgreSQL ログは、データベースアクティビティについての有用な情報を提供します。これらの情報は、パフォーマンス調整およびトラブルシューティングに役立ちます。この投稿では、ログの使い方を説明しました。これで、ニーズに合った方法を選択できるようになりました。

質問やご意見がある場合は、コメント欄にお考えを投稿してください。

 


本稿の執筆者について

Yaser Raja は、アマゾン ウェブ サービスでプロフェッショナルサービスチームのシニアコンサルタントを務めています。顧客と協力し、AWS クラウドでスケーラブルかつ可用性と安全性の高いソリューションの構築に取り組んでいます。彼の専門分野は、オンプレミスのデータベースの AWS RDS や Aurora PostgreSQL への同種間または異種間の移行です。