接続パラメーター target_session_attrsのエンハンス – PostgreSQL 14でコミットされた機能の先行紹介:技術者Blog
PostgreSQLインサイド

Greg Nancarrow

Fujitsu Australia Software Technology
Principal Software Development Engineer

はじめに

この記事では、PostgreSQL 14で利用可能になるデータベース接続関連の強化について説明します。この機能の歴史、使用方法、およびこの機能が提供するさまざまなメリットについて解説します。

背景

Greg
多くのPostgreSQLクライアントプログラムは、Cクライアントライブラリー「libpq」を使用してデータベースにアクセスします。libpqは、クライアントプログラムがPostgreSQLバックエンドサーバーに接続し、クエリを渡し、その結果を受け取るための関数群を提供します。
PostgreSQLはlibpqを通じて、接続文字列(または接続URI)をサポートします。この文字列は、ホスト名とポート番号の組み合わせを複数指定することができます。接続が正常に確立されるまで、各候補が順番に試されます。

複数ホストの指定は、PostgreSQL 10でサポートされました。その際、新しいパラメーターとして「target_session_attrs」が提供され、接続するバックエンドサーバーのタイプを指定できるようになりました。以降PostgreSQL 13までは、指定可能なパラメーター値は以下のみでした。

target_session_attrs パラメーターの値 意味
any(デフォルト) すべての接続が受付可能です。
read-write 読み書きトランザクションがデフォルトで許容される接続だけが受付可能になります。

PostgreSQL 11で、富士通は他の接続タイプに対応するためのパラメーター値の追加と、パラメーターの検証および接続時の内部処理の改善を提案しました。そして、この機能改善に向けて、PostgreSQLコミュニティーとのレビュー、協議、そして改善についての長いプロセスを開始しました。具体的には以下のやり取りがありました。

  • 複数の富士通開発者との協議。
  • 多数のパッチ・バージョンとパッチ・セットの変更:あるバージョンで、そして複数のPostgreSQLのバージョンにまたがって、パッチを結合、分割、およびリベースします。
  • 様々な意見やアイデアを持つ、多くのコミュニティーメンバーからのフィードバック。
  • 一部のメンバーからの機能追加の要求:例えば、類似するPostgreSQL JDBCドライバーパラメーターとの整合性と互換性の向上(これがさらなる開発とパッチ・バージョンを引き起こしましたが、最終的にこれらの追加は却下されました)。
  • コミッター自身による最終的な改善、微調整、単純化。

とても長い道のりでしたが、遂にPostgreSQL 14で、このlibpqのエンハンスがコミットされました!

機能概要

Greg
PostgreSQL 14は、target_session_attrs パラメーターに次の値をサポートします。新規の値はハイライトで表示しています。

target_session_attrs パラメーターの値 意味
any(デフォルト) 成功する接続はすべて受付可能です。
read-write セッションはデフォルトで読み書きトランザクションを受け入れる必要があります。(つまり、サーバーはホットスタンバイモードではなく、default_transaction_read_onlyパラメーターはoffであるべきです)
read-only セッションは、デフォルトでは読み書きトランザクションを受け入れません。(「read-write」の逆)(
primary サーバーがホットスタンバイモードであってはなりません。
standby サーバーはホットスタンバイモードでなければなりません。
prefer-standby 最初にスタンバイサーバーを探しますが、リストされたホストのいずれもスタンバイサーバーでない場合は、「any」モードで再試行します。
  • default_transaction_read_only設定パラメーターがonに設定されているため、PostgreSQLサーバーは読み取り専用であってもホットスタンバイモードではないことに注意してください。

サポートされるクライアント

libpqライブラリーをリンクするPostgreSQLクライアントは、target_session_attrs パラメーターと、ここで説明された機能の改善を利用することができます。これにはPostgreSQL言語サポートライブラリー(psycopg2[Python用ドライバー]やpsqlODBC[C言語インターフェイスを備えたPostgreSQL ODBCドライバー]など)のほとんどが含まれますが、PostgreSQL JDBCドライバーやNpgsql(PostgreSQL用ADO.NETデータ・プロバイダー)は含まれません。JDBCドライバーは、primary / secondary / preferSecondaryの値を受け付ける「targetServerType」接続パラメーターを使用して、同様の機能をサポートします。Npgsqlには現在同様の機能はありません。

接続パフォーマンスの向上

新しいtarget_session_attrs パラメーターの値に加え、PostgreSQL 14以降のサーバーに接続する際の接続パフォーマンスが改善されました。これは、セッションステータスに関連する報告可能な(GUC_REPORT)設定変数を使用することで実現されました。

GUC変数 説明
default_transaction_read_only PostgreSQL 14で報告可能(GUC_REPORT)にしました。
in_hot_standby PostgreSQL 14での新しいGUC_REPORT変数です。

これらは、接続が成功すると、セッション状態を決定するための余分なネットワークラウンドトリップを抑えながら、サーバーによってクライアントに直接報告されます。そのため、古いバージョンのサーバーに接続すると、SHOWクエリまたはSELECTクエリが発行され、セッションの読み取り専用状態またはサーバーのホットスタンバイ状態が検出されます。
セッション中にサーバーがプライマリーに昇格した場合、in_hot_standbyもクライアントに報告されることに注意してください。

「psql(PostgreSQLの端末ベースのフロントエンド)」はlibpqを使用しているため、コーディングすることなくtarget_session_attrs パラメーターのテストに使用することができ、便利です。2つの利用可能なローカルサーバーのいずれかに接続しようとするときに、異なるtarget_session_attrs パラメーターの値を使用する簡単な例を以下に示します。

2つのローカル・サーバー・インスタンスを作成して起動します(ポート5432および5433で実行)。デフォルトでは、どちらも読み書きトランザクションを受け入れます。

$ pg_ctl -D ./testdb1 initdb

$ pg_ctl -D ./testdb2 initdb

$ pg_ctl -D ./testdb1 -o '-p 5432' -l testdb_1.log start

$ pg_ctl -D ./testdb2 -o '-p 5433' -l testdb_2.log start

読み取り専用トランザクションのみを受け入れるサーバーへの接続を試みます。

$ psql "host=localhost,localhost port=5432,5433 dbname=postgres target_session_attrs=read-only"

psql: error: connection to server at "localhost" (::1), port 5432 failed: session is not read-only
connection to server at "localhost" (::1), port 5433 failed: session is not read-only

次に、testdb2/postgresql.confを編集して、「default_transaction_read_only = on」を追加します。再起動して接続を再試行します。

$ pg_ctl -D ./testdb2 -o '-p 5433' -l testdb_2.log restart

waiting for server to shut down.... done
server stopped
waiting for server to start.... done
server started

読み取り専用サーバーへの接続を試みます。

$ psql "host=localhost,localhost port=5432,5433 dbname=postgres target_session_attrs=read-only"

psql (14devel)
Type "help" for help.

postgres=# show port;
 port 
------
 5433
(1 row)

ホットスタンバイモードのサーバーへの接続を試みます。

$ psql "host=localhost,localhost port=5432,5433 dbname=postgres target_session_attrs=standby"

psql: error: connection to server at "localhost" (::1), port 5432 failed: server is not in hot standby mode
connection to server at "localhost" (::1), port 5433 failed: server is not in hot standby mode

プライマリサーバー(スタンバイモードではないサーバー)への接続を試みます。

$ psql "host=localhost,localhost port=5432,5433 dbname=postgres target_session_attrs=primary"

psql (14devel)
Type "help" for help.

postgres=# show port;
 port 
------
 5432
(1 row)

ホットスタンバイモードのサーバーへの接続を優先します。

$ psql "host=localhost,localhost port=5432,5433 dbname=postgres target_session_attrs=prefer-standby"

psql (14devel)
Type "help" for help.

postgres=# show port;
 port 
------
 5432
(1 row)

まとめ

Greg
新たにサポートされたtarget_session_attrs パラメーターの値により、クライアントが希望するターゲットサーバー接続をより細かく選択できるようになり、マルチホスト接続に役立ちます。また、プライマリサーバーの負荷を軽減するために、読み取り専用の要求をスタンバイサーバーにリダイレクトできるなど、スケーリングの初歩的な形式も提供します。これらの新しいtarget_session_attrs パラメーターの値によって、より柔軟にマルチホスト接続文字列 / URIを指定できるため、一部のPostgreSQLフェイルオーバーソリューションでは、利用可能なサーバーに再接続する際の利便性が向上するでしょう。

2021年6月11日公開

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

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

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

お電話でのお問い合わせ

Webでのお問い合わせ

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

ページの先頭へ