Connection pooling
==================

クライアント全体でバックエンド接続を再利用するように接続プーリングを構成し、サーバーメモリのオーバーヘッドを削減し、多くの短期間のセッションを含むワークロードのスループットを向上させます。
Connection
Managerのビルトインプーリングにより、ほとんどの展開でpgBouncerなどの外部ツールの必要性がなくなります。

DBAセットアップと移行ガイダンスについては :ref:`Configuring connection pooling <Configuring connection pooling>` を、開発者ガイダンスについては :ref:`Using connection pooling in your application <Using connection pooling in your application>` を参照してください。

プールモードの構成
------------------

``bdr.alter_node_group_option``
を使用してノードグループのプールモードを設定します。

.. code:: sql

   SELECT bdr.alter_node_group_option(mygroup, server_pool_mode, transaction);

またはPGD CLIを使用して

.. code:: shell

   pgd group mygroup set-option server_pool_mode transaction

``server_pool_mode`` グループオプションは、プーリング動作を制御します。

.. csv-table::
  :header: Mode,Behavior
  :widths: 10,30
  :align: left
  :class: longtable

  `none`,プーリングはありません。各クライアント接続は、その有効期間全体にわたって専用のバックエンド接続を取得します。クライアントが切断すると、バックエンド接続が閉じます。このモードはデフォルトです。
  `session`,バックエンド接続は、最初に使用するときにクライアントに割り当てられ、クライアントが切断するとプールに返されます。接続マネージャーは、再利用のために接続を返し、セッション状態をリセットする前に :ref:`pg_upgrade <Monitoring through SQL>` を実行します。
  `transaction`,バックエンド接続は、トランザクションの開始時に割り当てられ、トランザクションが終了するとプールに返されます。トランザクション間では、クライアントはバックエンド接続を保持しないため、他のクライアントが利用できるようにします。再利用のために接続を返す前に、接続マネージャーは`server_reset_mode`グループオプションに従ってそれをクリーンアップし、次のトランザクションにクライアントがサポートされている接続パラメーターを再適用します。  :ref:`リセットモードの構成<リセットモードの構成>` を参照してください。

現在のプールモードは、 :ref:`bdr.node_group_summary <bdr.node_group_summary>` ビューの\ ``server_pool_mode``
列に表示されます。

リセットモードの構成
--------------------

ノードグループのリセットモードを設定して、接続マネージャーがプールされたバックエンド接続を再利用のためにプールに返す前にクリーンアップする方法を制御します。このオプションは\ ``transaction``
プールモードでのみ有効です。 ``session``
モードのクリーンアップ動作については、 :ref:`プールモードの構成 <プールモードの構成>` を参照してください。

クリーンアップがないと、バックエンド接続は、オープントランザクション、プリペアドステートメント、\ ``SET``
値、一時テーブル、またはアドバイザリロックなど、それを使用したクライアントが残したセッション状態を引き継ぐ場合があります。

``bdr.alter_node_group_option`` を使用します。

.. code:: sql

   SELECT bdr.alter_node_group_option(mygroup, server_reset_mode, <value>);

または、 PGD CLIを使用します。

.. code:: shell

   pgd group mygroup set-option server_reset_mode <value>

``server_reset_mode``
オプションは2つの値を受け入れます。現在のリセットモードは、
:ref:`bdr.node_group_summary <bdr.node_group_summary>` ビューの\ ``server_reset_mode`` 列に表示されます。

.. csv-table::
  :header: Value,Behavior
  :widths: 10,30
  :align: left
  :class: longtable

  `discard_all`,接続マネージャーは、再利用のために接続を返し、セッション状態をリセットする前に`DISCARD ALL`を実行します。この値はデフォルトです。
  `fast`,接続マネージャーは、実際に必要な場合を除き、クリーンアップをスキップします。クライアントがトランザクションを開いたままにしている場合、接続マネージャーはそれをロールバックします。バックエンドでキャッシュされたプリペアドステートメントの数が`server_max_prepared_statements`グループオプションを超える場合、Connection Managerは`DEALLOCATE ALL`を実行します。それ以外の場合、接続はすぐにプールに戻り、クリーンアップクエリーはまったくありません。セッションレベルの`SET`値のリセット、アドバイザリーロックのリリース、または一時テーブルのクリーンアップは行わないため、あるクライアントのトランザクションによって残された状態は、次にそのバックエンド接続が割り当てられるクライアントのトランザクションから可視できます。

``fast`` は、 ``discard_all``
のクリーンアップ保証と引き換えに、すべてのトランザクションの後に実行するのではなくリセットクエリをスキップする
`PgBouncer's transaction pooling default <https://www.pgbouncer.org/config.html#server_reset_query>`_  と同じアプローチに従います。
:ref:`未サポートの機能 <未サポートの機能>` にリストされている機能を既に回避しているアプリケーションにのみ有効にします。

セッションパラメーターの管理
----------------------------

接続マネージャーは、すべてのプールモードでバックエンドに特定の接続パラメーターのセットを転送します。認識するパラメーターは\ ``client_encoding``
、\ ``DateStyle`` 、\ ``TimeZone`` 、\ ``standard_conforming_strings``
、\ ``application_name`` 、\ ``search_path``
、および\ ``extra_float_digits`` です。 ``-c name=value``
構文を使用して、\ ``options``
接続パラメーターを介して追加パラメーターを含めることができます。

トランザクション間でバックエンド接続が変更される可能性がある\ ``transaction``
モードでは、接続マネージャーは新しいバックエンドを割り当てるたびにこれらのパラメーターを再適用します。接続パラメーターのみが再適用されるため、
``SET``
コマンドを使用してトランザクションモードでセッションパラメーターを構成することは避けてください。
``SET``
で行われた変更は、バックエンド接続が変更されたときに保持されません。接続文字列の例については、
:ref:`Using connection pooling in your application <Using connection pooling in your application>` を参照してください。

準備されたステートメントを使用する
----------------------------------

拡張クエリプロトコルを介して送信されるプリペアドステートメントは、すべてのプールモードのトランザクションにわたってシームレスに動作します。接続マネージャーは、バックエンドで欠落しているプリペアドステートメントを自動的に検出し、オンデマンドで再準備し、クライアントとバックエンド間でステートメントの名前付けを透過的に管理します。

デフォルトの\ ``discard_all`` リセットモードを使用する\ ``transaction``
モードでは、各トランザクションの最後にバックエンド接続がプールに返されたときに\ ``DISCARD ALL``
が実行され、\ ``PREPARE`` /``EXECUTE``
SQLステートメントで作成されたプリペアドステートメントの割り当てが解除されます。
``fast`` リセットモードでは、 ``PREPARE`` / ``EXECUTE``
で作成されたプリペアドステートメントは、それを作成したトランザクションを超えてバックエンドで生き残ることができますが、その同じバックエンド接続を使用する次のトランザクションは同じクライアントからであることが保証されていないため、それに依存するまだ存在するのは安全ではありません。いずれの場合も、
``PREPARE`` /``EXECUTE``
SQLステートメントを使用するトランザクション内で発行するか、代わりに拡張照会プロトコルを使用します。具体的な手順については、開発者ガイドの :ref:`準備されたステートメントを使用する <準備されたステートメントを使用する>` を参照してください。

接続の再利用
------------

``session`` および\ ``transaction``
モードでは、クライアントが切断されるか、トランザクションが終了すると、接続マネージャーはバックエンド接続をプールに返します。クライアントがサポートされていない機能をトリガーするか、保留中のコマンドで接続を閉じると、接続マネージャーはそのバックエンド接続をプールに返すのではなく、破棄します。他のクライアントは影響を受けません。

未サポートの機能
----------------

一部のPostgres機能は、\ ``server_reset_mode``
に関係なく、\ ``transaction`` モードではサポートされていません。
``discard_all`` では、 ``DISCARD ALL``
が依存する状態をクリアするため、これらに依存すると予想通り失敗します。
``fast``
では、そのクリーンアップがスキップされるため、障害は予測できず、代わりに状態が持続して別のクライアントのトランザクションにリークする可能性があります。すでに次のすべてを回避しているアプリケーションの場合にのみ\ ``fast``
モードを有効にします。

- セッション中に行われた\ ``SET`` 変更は、 ``transaction``
  モードでは持続しません。代わりに、接続文字列でセッションパラメーターを構成します。詳細は、
  :ref:`セッションパラメーターの管理 <セッションパラメーターの管理>` を参照してください。

- ``PREPARE`` /``EXECUTE`` /``DEALLOCATE``
  SQLステートメントは\ ``transaction``
  モードではサポートされていません。これらのステートメントを使用するトランザクション内で発行するか、代わりに拡張照会プロトコルを使用します。詳細は、
  :ref:`準備されたステートメントを使用する <準備されたステートメントを使用する>` を参照してください。

- ホールダブルカーソル\ ``WITH HOLD`` は、\ ``transaction``
  モードではサポートされていません。これらはトランザクション境界を超えて持続するため、トランザクションの終了時にバックエンド接続をプールに返すことと競合します。

- ``LISTEN`` は\ ``transaction`` モードではサポートされていません。
  ``LISTEN``
  サブスクリプションは、単一のトランザクションを超えて持続します。これは、バックエンド接続をプールに返すことと競合します。

- トランザクション境界を越えて保持されるアドバイザリロックは、
  ``transaction`` モードではサポートされていません。

- トランザクションを超えてアクセスされる一時テーブルは、 ``transaction``
  モードではサポートされていません。

- レプリケーション接続はすべてのプールモードで拒否されます。
