

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 避免鎖定 RDS Proxy
<a name="rds-proxy-pinning"></a>

 當資料庫請求不依賴先前請求的狀態資訊時，多工會更有效率。在這種情況下，RDS Proxy 可以在每一筆交易結束時重複使用連線。這類狀態資訊的範例包括您可以透過 `SET` 或 `SELECT` 陳述式變更的大部分變數和組態參數。根據預設，用戶端連線上的 SQL 交易可以在基礎資料庫連線之間進行多工。

 您與代理的連線可能會進入一種稱為*鎖定*的狀態。連線被鎖定時，每一筆後續交易都會使用相同的基礎資料庫連線，直到工作階段結束為止。其他用戶端連線也無法重複使用該資料庫連線，直到工作階段結束為止。工作階段會在用戶端連線中斷時結束。

 在偵測到不適用於其他工作階段的工作階段狀態變更時，RDS Proxy 會自動將用戶端連線鎖定至特定資料庫連線。鎖定會降低連線重複使用的有效性。如果所有或幾乎所有的連線都遭遇鎖定，請考慮修改應用程式的程式碼或工作負載，以減少導致鎖定的情況。

例如，您的應用程式變更了工作階段變數或組態參數。在此情況下，稍後的陳述式可能會依賴新的變數或參數才會生效。因此，當 RDS Proxy 處理請求，而變更工作階段變數或組態設定時，會將該工作階段到資料庫的連線鎖定。這樣一來，工作階段狀態對於同一工作階段中的所有後續交易仍然有效。

 對於部分資料庫引擎，此規則不適用於您可以設定的所有參數。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
+ USE

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 指標和其他 CloudWatch 指標的資訊，請參閱 [使用 Amazon CloudWatch 監控 RDS Proxy 指標使用 CloudWatch 監控 RDS Proxy](rds-proxy.monitoring.md)。
+  如果您使用 `SET` 陳述式為每個用戶端連線執行相同的初始化，您可以執行此操作，同時保留交易層級的多工。在此情況下，您可以將設定初始工作階段狀態的陳述式移至代理所使用的初始化查詢中。此屬性為一包含一個或多個以分號分隔的 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 Server 鎖定的條件
<a name="rds-proxy-pinning.sqlserver"></a>

 若為 RDS for SQL Server，下列互動也會導致鎖定：
+ 使用多個作用中結果集 (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 Proxy 目前與會建立可在所有交易之間持續存在的暫時資料表之預存程序不相容。
+ 具有 MySQL （語法 /\$1！ ... \$1/) 或 MariaDB （語法 /\$1M！ ... \$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 Proxy 不會鎖定交易層級諮詢鎖定，特別是 `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 Proxy 目前與會建立可在所有交易之間持續存在的暫時資料表之預存程序不相容。
+ 捨棄工作階段狀態。如果您使用連線集區程式庫，並將 `DISCARD ALL` 查詢設定為重設查詢，RDS Proxy 會在發行時鎖定您的用戶端連線。這會降低代理的多工效率，並可能導致非預期的結果，因為 `DISCARD ALL` 命令可能會干擾工作階段狀態管理。