postgres_fdwにおけるappication_nameのパラメーター化 - PostgreSQL 15でコミットされた機能の紹介:技術者Blog
PostgreSQLインサイド

黒田 隼人

富士通株式会社
ソフトウェアオープンイノベーション事業本部 データマネジメント事業部

はじめに

本記事では、postgres_fdwに新たに追加されたパラメーターであるpostgres_fdw.application_nameについて紹介します。

目次

背景 - 外部データラッパーと接続の確立

postgres_fdwとは、外部のPostgreSQLサーバーに格納されたデータへアクセスするために使用する外部データラッパー(Foreign Data Wrapper, FDW)です。外部のデータベースへ接続する際には、内部的にCクライアントライブラリーである「libpq」を使用しています。
PostgreSQLクライアントプログラムがlibpqを使用する場合、「application_name」という接続パラメーターが指定できます。これは接続元のアプリケーションを識別するためのものであり、ログから各アプリケーションのアクティビティを監視するために活用できます。また似たような接続パラメーターとして「fallback_application_name」が存在し、こちらは上書き可能なデフォルトのアプリケーション名を指定するために使用します。

既存の動作の問題点 - 実際の例から

postgres_fdwが外部のPostgreSQLサーバーへ接続する際には、fallback_application_nameには固定の文字列「postgres_fdw」が使用されています。よってユーザーが特別な設定をしていない場合、外部のPostgreSQLサーバーからは「postgres_fdw」というアプリケーションが接続してきたと判断されます。このとき、ユーザーが構築するシステムによっては、詳細なシステム状態の監視・解析が難しいことがありました。

1つ例を挙げてみましょう。分析用PostgreSQLサーバー(Analyzer)が1台存在し、postgres_fdwを通じてデータ格納用サーバーへアクセスしています。データ格納用PostgreSQLサーバー(Source)上での動作を元に業務システムを改善するため、データ格納用サーバーのログ出力設定を少し変更し、接続パラメーターapplication_nameとSQL実行時間を表示しているとしましょう。さて、あるときデータ格納用サーバーのログを確認してみると、いくつかのSQLの実行に非常に時間がかかっていることが分かりました(図1のduration部分)。この現象を解明するため、実行したクライアントを探ろうとアプリケーション名を確認すると、すべて”postgres_fdw”と記載されています。このSQLは、どのユーザーが送ったものでしょうか?また各セッションではどのような順序でSQLを送ったのでしょうか?見分ける手段はありませんでした。(注1)

分析用PostgreSQLサーバーからデータ格納用PostgreSQLサーバーへのアクセス
図1:分析用PostgreSQLサーバーからデータ格納用PostgreSQLサーバーへのアクセス

  • 注1)

    複数の分析用PostgreSQLサーバーが同一のデータへアクセスし、参照および更新を行うシステムでは、CREATE SERVER文のOPTIONSの接続パラメーターにapplication_nameを記載することで、接続元サーバーを識別することは可能です。しかしながら、同一サーバーから同時にセッションを貼られる場合、データ格納用サーバーはこれらを識別することはできませんでした。

機能の概要

そこで私は、postgres_fdwに新たな文字列パラメーター「postgres_fdw.application_name」の追加をPostgreSQLコミュニティーに提案しました。
postgres_fdwが新たに接続を確立する際に、このパラメーターが設定されている場合は、指定された文字列をlibpq接続パラメーターとして使用します。このパラメーターはpostgresql.confからの指定に加えて、SET文を使用したセッション単位での指定・変更ができます。

-- pg_settingsビューでの確認
postgres=# SELECT name, short_desc, context, vartype from pg_settings WHERE name = 'postgres_fdw.application_name';
-[ RECORD 1 ]----------------------------------------------------------
name       | postgres_fdw.application_name
short_desc | Sets the application name to be used on the remote server.
context    | user
vartype    | string

-- SET文によりセッション単位で変更が可能
postgres=# SET postgres_fdw.application_name TO 'test wrapper'
SET
postgres=# SHOW postgres_fdw.application_name;
 postgres_fdw.application_name 
-------------------------------
 test wrapper
(1 row)

なお、すでに確立済みの接続に対して、application_nameを上書きすることはできません。SET文で新たに指定したパラメーターを使用したい場合は、postgres_fdw_disconnect()関数やpostgres_fdw_disconnect_all()関数を使用し、外部のPostgreSQLサーバーとの接続を切断した後、再度接続を確立する必要があります。
このパラメーターの重要な特徴は、log_line_prefixパラメーターのように、文字列に接続元サーバーの情報を埋め込めることです。パラメーターに指定された特定の文字列は、application_nameとして使用される際に、接続元サーバーの情報へ置き換えられます。具体的なエスケープ文字列と、変換先の文字列は以下の通りです。

エスケープ文字 変換先
%a 接続元サーバー上でのapplication_name
%c 接続元サーバー上でのセッションID
%C 接続元サーバー上でのクラスタ名
%u 接続元サーバー上でのユーザー名
%d 接続元サーバー上でのデータベース名
%p 接続元サーバー上でのバックエンドプロセスのpid
%% リテラルの%

効果 - 実際の例

本機能を利用した場合、ユーザーにはどのようなメリットがあるでしょうか?図1を元に説明します。

上で述べた例では、1台の分析用PostgreSQLサーバーから同時に複数のユーザーがアクセスしたためにログを用いたシステムの追跡が難しくなっていました。そこで、postgres_fdw.application_nameを用いてこの問題を解決してみましょう。パラメーターを変更する方法としては設定ファイルを直接更新する方法がありますが、下記のようにALTER SYSTEM文を使用することもできます。

-- ALTER SYSTEM文によるパラメーターの変更
postgres=# ALTER SYSTEM SET postgres_fdw.application_name TO 'from %C user=%u';
ALTER SYSTEM
-- SIGHUPシグナルを送り、postgresql.auto.confを再読み込みさせる
postgres=# SELECT pg_reload_conf();
 pg_reload_conf 
----------------
 t
(1 row)
-- 設定内容の確認。正しく変更されている。
-- エスケープ文字は外部のPostgreSQLサーバーへの接続時に変換されるため、ここでは実際のapplication_nameを確認することはできない
postgres=# SHOW postgres_fdw.application_name;
 postgres_fdw.application_name 
-------------------------------
 from %C user=%u
(1 row)

この設定を行ったうえで、業務システムを再開してみます。ログを再度確認してみると、下記のように出力されていました。

分析用PostgreSQLサーバーからデータ格納用PostgreSQLサーバーへのアクセス(postgres_fdw.application_nameを使用した場合)
図2:分析用PostgreSQLサーバーからデータ格納用PostgreSQLサーバーへのアクセス(postgres_fdw.application_nameを使用した場合)

postgres_fdw.application_nameに設定した値と見比べてみると、%Cがクラスタ名である”Analyzer”に、%uがAnalyzer上でのユーザー名である”kuroda”および”takeda”へ置換されていることが分かります。これらのアプリケーション名を用いて、分析用PostgreSQLサーバーと、データ格納用PostgreSQLサーバーの間で、ログを突き合せた正しいワークロードの分析が行えるようになりました。
上記のようにALTER SYSTEM文を用いてパラメーターを設定すると、業務システムを変更することなくこのパラメーターを活用することができます。また、業務システムを改修し、SET文を使用することで処理種別ごとにapplication_nameを変更することも可能です。

まとめ

今回はpostgres_fdwの内部動作やその問題点、そして解決策である新たなパラメーターについて説明しました。データシャーディングやスケールアウト構成(注2)といった複数のデータベースクラスタを活用したソリューションは、今後ますます必要性を増してくると考えられます。fdwを用いてそれらの機能を実現する際に、システムの監視がしやすくなるpostgres_fdw.application_nameは有用となるでしょう。
このほかにも、postgres_fdwには日々新しい機能が提案、追加されています。現在私が取り組んでいるのは、外部のPostgreSQLサーバーとの接続状態を確認する新たな関数を追加することです。提案が受け入れられた際には、再度このブログで取り上げたいと思っています。

注意事項

本パラメーターには任意の長さの文字列を指定できますが、application_nameとして使用される際には文字列長がNAMEDATALEN(通常は64)以下となるまで切り詰められます。また本パラメーターにASCII文字以外を指定することもできますが、そのような文字はapplication_nameとして使用される際にクエスチョンマーク(?) へ置換されます。

詳細情報

本ブログで解説した本機能についての詳細は、PostgreSQL文書またはGitHubに投稿したコミット情報をご覧ください。

2023年4月14日公開

オンデマンド(動画)セミナー

    • PostgreSQLに関連するセミナー動画を公開中。いつでもセミナーをご覧いただけます。
      • 【事例解説】運送業務改革をもたらす次世代の運送業界向けDXプラットフォームの構築
      • ハイブリッドクラウドに最適なOSSベースのデータベースご紹介

本コンテンツに関するお問い合わせ

お電話でのお問い合わせ

Webでのお問い合わせ

当社はセキュリティ保護の観点からSSL技術を使用しております。

ページの先頭へ