

# RDS Proxy の固定の回避
<a name="rds-proxy-pinning"></a>

 データベースリクエストが以前のリクエストの状態情報に依存しない場合、多重化の効率が高まります。その場合、RDS Proxy は、各トランザクションの終了時に接続を再利用できます。このような状態情報の例には、`SET` ステートメントや `SELECT` ステートメントで変更できるほとんどの可変や設定パラメータが含まれます。クライアント接続の SQL トランザクションでは、デフォルトで、基となるデータベース接続を多重化できます。

 プロキシへの接続は、*固定*と呼ばれる状態に入る場合があります。接続が固定されると、以降の各トランザクションは、セッションが終了するまで、同じ基になるデータベース接続を使用します。また、他のクライアント接続は、セッションが終了するまでそのデータベース接続を再利用できません。クライアント接続がドロップされると、セッションは終了します。

 RDS Proxy は、他のセッションに不適切なセッション状態の変化を検出すると、クライアント接続を特定の DB 接続に自動的に固定します。固定により、接続の再利用の有効性が低下します。すべての接続やほぼすべての接続で固定が発生する場合は、固定が発生する状態を減らすようにアプリケーションコードやワークロードを変更します。

例えば、アプリケーションによってセッションの変数や設定パラメータが変更されたとします。この場合、後続のステートメントは変更後の変数やパラメータが有効かどうかによって変わります。したがって、RDS Proxy はセッションの可変や構成設定の変更リクエストを処理する場合、そのセッションを DB 接続に固定します。これにより、セッション状態は、同じセッション内の後続のすべてのトランザクションで有効になります。

 一部のデータベースエンジンでは、設定可能なすべてのパラメータにこのルールが適用されるわけではありません。RDS Proxy は、特定のステートメントと変数を追跡します。したがって、これらの変更時に RDS Proxy はセッションを固定しません。この場合、RDS Proxy は、これらの設定の値が同じである他のセッションでのみ、接続を再利用します。RDS Proxy がデータベースエンジンで追跡する内容の詳細については、以下を参照してください。
+ [RDS Proxy が RDS for SQL Server データベースに対して追跡する内容](#rds-proxy-pinning.sql-server-tracked-vars)
+ [RDS Proxy が RDS for MariaDB および RDS for MySQL データベースに対して追跡する内容](#rds-proxy-pinning.mysql-tracked-vars)

## RDS Proxy が RDS for SQL Server データベースに対して追跡する内容
<a name="rds-proxy-pinning.sql-server-tracked-vars"></a>

RDS Proxy が追跡する SQL Server のステートメントは以下のとおりです。
+ `USE`
+ `SET ANSI_NULLS`
+ `SET ANSI_PADDING`
+ `SET ANSI_WARNINGS`
+ `SET ARITHABORT`
+ `SET CONCAT_NULL_YIELDS_NULL`
+ `SET CURSOR_CLOSE_ON_COMMIT`
+ `SET DATEFIRST`
+ `SET DATEFORMAT`
+ `SET LANGUAGE`
+ `SET LOCK_TIMEOUT`
+ `SET NUMERIC_ROUNDABORT`
+ `SET QUOTED_IDENTIFIER`
+ `SET TEXTSIZE`
+ `SET TRANSACTION ISOLATION LEVEL`

## RDS Proxy が RDS for MariaDB および RDS for MySQL データベースに対して追跡する内容
<a name="rds-proxy-pinning.mysql-tracked-vars"></a>

RDS Proxy が追跡する MariaDB および MySQL のステートメントは以下のとおりです。
+ DROP DATABASE
+ DROP SCHEMA
+ 使用

RDS Proxy が追跡する MySQL および MariaDB の変数は以下のとおりです。
+ `AUTOCOMMIT`
+ `AUTO_INCREMENT_INCREMENT`
+ `CHARACTER SET (or CHAR SET)`
+ `CHARACTER_SET_CLIENT`
+ `CHARACTER_SET_DATABASE`
+ `CHARACTER_SET_FILESYSTEM`
+ `CHARACTER_SET_CONNECTION`
+ `CHARACTER_SET_RESULTS`
+ `CHARACTER_SET_SERVER`
+ `COLLATION_CONNECTION`
+ `COLLATION_DATABASE`
+ `COLLATION_SERVER`
+ `INTERACTIVE_TIMEOUT`
+ `NAMES`
+ `NET_WRITE_TIMEOUT`
+ `QUERY_CACHE_TYPE`
+ `SESSION_TRACK_SCHEMA`
+ `SQL_MODE`
+ `TIME_ZONE`
+ `TRANSACTION_ISOLATION (or TX_ISOLATION)`
+ `TRANSACTION_READ_ONLY (or TX_READ_ONLY)`
+ `WAIT_TIMEOUT`

**注記**  
RDS Proxy は、セッションスコープで設定すると、`TRANSACTION_ISOLATION` 変数と `TRANSACTION_READ_ONLY` 変数の変更を追跡します。ただし、次のトランザクションスコープで設定すると、RDS Proxy は接続を固定します。この動作は、`SET` ステートメントと `SET TRANSACTION` ステートメントのどちらを使用してこれらの値を設定する場合でも適用されます。

## 固定を最小化する
<a name="rds-proxy-pinning.minimizing"></a>

 RDS Proxy のパフォーマンスチューニングでは、固定を最小化してトランザクションレベルの接続の再利用 (多重化) を最大化します。

以下の方法で、固定を最小化できます。
+  固定の原因となる可能性のある不要なデータベースリクエストを避けます。
+  すべての接続間で可変と構成設定を一貫して設定します。これにより、これらの特定の設定を持つ接続が後続のセッションで再利用される可能性が高くなります。

   ただし、PostgreSQL では、可変の設定によりセッションの固定が発生します。
+  MySQL エンジンファミリデータベースの場合、セッション固定フィルターをプロキシに適用します。特定の種類のオペレーションがアプリケーションの正常な動作に影響しないことがわかっている場合、これらのオペレーションを除外してセッションの固定を起こさないように指定できます。
+  Amazon CloudWatch メトリクス `DatabaseConnectionsCurrentlySessionPinned` をモニタリングして、固定が発生する頻度を確認します。このメトリクスおよび他の CloudWatch メトリクスの詳細については、「[Amazon CloudWatch を使用した RDS Proxy メトリクスのモニタリングCloudWatch を使用した RDS Proxy のモニタリング](rds-proxy.monitoring.md)」を参照してください。
+  `SET` ステートメントを使用して各クライアント接続を同等に初期化する場合、トランザクションレベルの多重化を維持したまま、この初期化を実行できます。この場合、初期セッション状態を設定するステートメントを、プロキシが使用する初期化クエリに移動します。このプロパティは、セミコロンで区切られた 1 つ以上の SQL ステートメントを含む文字列です。

   例えば、特定の設定パラメータを設定する初期化クエリをプロキシに定義できます。これにより、RDS Proxy でプロキシの新しい接続を設定するたびに、これらの設定が適用されます。トランザクションレベルの多重化を妨げないように、アプリケーションコードから対応する `SET` ステートメントを削除できます。

   プロキシでの固定の発生回数のメトリクスについては、「[Amazon CloudWatch を使用した RDS Proxy メトリクスのモニタリングCloudWatch を使用した RDS Proxy のモニタリング](rds-proxy.monitoring.md)」を参照してください。

## すべてのエンジンファミリーで固定が発生する条件
<a name="rds-proxy-pinning.all"></a>

 以下の場合は、多重化が予期しない動作をもたらす可能性があるため、プロキシはセッションを現在の接続に固定します。
+ ステートメントのテキストサイズが 16 KB を超える場合、プロキシはセッションを固定します。

## RDS for Microsoft SQL で固定が発生する条件
<a name="rds-proxy-pinning.sqlserver"></a>

 RDS for SQL サーバーでは、次の操作でも固定が発生します。
+ 複数のアクティブな結果セット (MARS) の使用。MARS の詳細については、[SQL Server](https://docs.microsoft.com/en-us/sql/relational-databases/native-client/features/using-multiple-active-result-sets-mars?view=sql-server-ver16) のドキュメントを参照してください。
+ 分散トランザクションコーディネーター (DTC) 通信の使用。
+ 一時テーブル、トランザクション、カーソル、準備済みステートメントの作成。
+ 次の `SET` ステートメントを使用してください。
  + `SET ANSI_DEFAULTS`
  + `SET ANSI_NULL_DFLT`
  + `SET ARITHIGNORE`
  + `SET DEADLOCK_PRIORITY`
  + `SET FIPS_FLAGGER`
  + `SET FMTONLY`
  + `SET FORCEPLAN`
  + `SET IDENTITY_INSERT`
  + `SET NOCOUNT`
  + `SET NOEXEC`
  + `SET OFFSETS`
  + `SET PARSEONLY`
  + `SET QUERY_GOVERNOR_COST_LIMIT`
  + `SET REMOTE_PROC_TRANSACTIONS`
  + `SET ROWCOUNT`
  + `SET SHOWPLAN_ALL`、`SHOWPLAN_TEXT`、および `SHOWPLAN_XML`
  + `SET STATISTICS`
  + `SET XACT_ABORT`

## RDS for MariaDB と RDS for MySQL で固定が発生する条件
<a name="rds-proxy-pinning.mysql"></a>

 MariaDB と MySQL の場合、次の操作に伴ってピニングも発生します。
+ 明示的なテーブルロックステートメントである `LOCK TABLE`、`LOCK TABLES`、または `FLUSH TABLES WITH READ LOCK` が原因でプロキシによるセッションの固定が発生します。
+ `GET_LOCK` を使用して名前付きロックを作成するプロキシはセッションを固定します。
+ ユーザー変数またはシステム変数を設定すると (一部例外あり)、セッションはプロキシに固定されます。これにより接続の再利用が大幅に制限される場合は、固定されないように `SET` オペレーションを設定できます。これを行うには、セッション固定フィルターのプロパティを調整します。詳細については、「[Amazon RDS のプロキシの作成](rds-proxy-creating.md)」および「[RDS Proxy の変更](rds-proxy-modifying-proxy.md)」を参照してください。
+ 一時テーブルを作成した場合、プロキシはセッションを固定します。これにより、トランザクションの境界に関係なく、一時テーブルの内容がセッション全体で保持されます。
+ 関数 `ROW_COUNT` および `FOUND_ROWS` を呼び出すと、固定が発生する場合があります。
+ プリペアドステートメントの場合、プロキシはセッションを固定します。このルールは、プリペアドステートメントで SQL テキストを使用するか、バイナリプロトコルを使用するかに関係なく、適用されます。
+ SET LOCAL を使用する場合、RDS Proxy は接続を固定しません。
+ ストアドプロシージャやストアド関数を呼び出しても、固定は発生しません。RDS Proxy は、このような呼び出しに伴うセッション状態の変更を検出しません。トランザクション間でのセッション状態の維持を活用している場合は、アプリケーションがストアド ルーチン内でセッション状態を変更しないようにする必要があります。例えば、RDS プロキシは現在、すべてのトランザクションにわたって永続化される一時テーブルを作成するストアドプロシージャと互換性がありません。
+ MySQL (構文 /\$1\$1 ... \$1/) または MariaDB (構文 /\$1M\$1 ... \$1/) の実行可能なコメントを含むクエリでは、ピン留めが発生します。RDS Proxy は、これらのコメントに埋め込まれた SQL を解析してセッション状態の変化を追跡することはできません。

 アプリケーションの動作に関する専門知識がある場合は、特定のアプリケーションステートメントについて固定動作をスキップできます。これを行うには、プロキシの作成時に [**セッションの固定フィルタ**] オプションを選択します。現在、セッションの可変や構成設定の定義により発生するセッションの固定を回避できます。

## RDS for PostgreSQL で固定が発生する条件
<a name="rds-proxy-pinning.postgres"></a>

 PostgreSQL の場合、次の操作に伴って固定も発生します。
+  `SET` コマンドの使用
+  `PREPARE` コマンド、`DISCARD` コマンド、`DEALLOCATE` コマンド、または `EXECUTE` コマンドを使用したプリペアドステートメントの管理
+  一時シーケンス、テーブル、またはビューの作成
+  カーソルの宣言
+  セッション状態の破棄
+  通知チャネルでのリッスン
+  `auto_explain` などのライブラリモジュールのロード
+  `nextval` や `setval` などの関数を使用したシーケンスの操作
+  `pg_advisory_lock` や `pg_try_advisory_lock` などの関数を使用したロックの操作 
**注記**  
RDS プロキシは、トランザクションレベルのアドバイザリロック (特に `pg_advisory_xact_lock`、`pg_advisory_xact_lock_shared`、`pg_try_advisory_xact_lock`、`pg_try_advisory_xact_lock_shared`) をピン留めしません。
+ パラメータの設定、またはパラメータのデフォルトへのリセット。具体的には、`SET` コマンドと `set_config` コマンドを使用して、セッション変数にデフォルト値を割り当てます。
+ ストアドプロシージャやストアド関数を呼び出しても、固定は発生しません。RDS Proxy は、このような呼び出しに伴うセッション状態の変更を検出しません。トランザクション間でのセッション状態の維持を活用している場合は、アプリケーションがストアド ルーチン内でセッション状態を変更しないようにする必要があります。例えば、RDS プロキシは現在、すべてのトランザクションにわたって永続化される一時テーブルを作成するストアドプロシージャと互換性がありません。
+ セッション状態の破棄。使用している接続プールライブラリで `DISCARD ALL` クエリをリセットクエリとして設定した場合、RDS Proxy は解放時にクライアント接続を固定します。これに伴って、`DISCARD ALL` コマンドがセッション状態の管理を妨げる場合があり、プロキシの多重化効率が低下し、予期しない結果につながる可能性があります。