

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

# 在 Amazon Aurora MySQL 資料庫叢集中使用本機寫入轉送
<a name="aurora-mysql-write-forwarding"></a>

*本機 (叢集內) 寫入轉送*允許您的應用程式直接在 Aurora 複本上發出讀取/寫入交易。然後，這些交易會轉送至要提交的寫入器資料庫執行個體。您可以當應用程式要求*先寫後讀一致性*時使用本機寫入轉送，能夠讀取交易中最新寫入的能力。

僅供讀取複本會以非同步方式從寫入器接收更新。如果沒有寫入轉送，您必須在寫入器資料庫執行個體上處理任何需要先寫後讀一致性的讀取。否則，您必須開發複雜的自訂應用程式邏輯，才能利用多個僅供讀取複本來實現可擴展性。您的應用程式必須完全拆分所有讀取和寫入流量，維護兩組資料庫連線，才能將流量傳送到正確的端點。當查詢是應用程式內單一邏輯工作階段的一部分，或是交易時，這類部署會讓應用程式設計過於複雜。此外，由於僅供讀取複本的複寫延遲可能不同，因此很難在資料庫中的所有執行個體達到全域讀取一致性。

寫入轉送可以避免拆分交易或以專門的方式傳送至寫入器，進而簡化應用程式開發作業。借助這項新功能，可讓您輕鬆現需要讀取交易最新寫入並且工作負載對寫入延遲不敏感的讀取擴展。

本機寫入轉送與全域寫入轉送不同，全域寫入轉送會將寫入從次要資料庫叢集轉送至 Aurora 全球資料庫中的主要資料庫叢集。您可以在屬於 Aurora 全球資料庫一部分的資料庫叢集中使用本機寫入轉送。如需詳細資訊，請參閱[在 Amazon Aurora 全域資料庫中使用寫入轉送](aurora-global-database-write-forwarding.md)。

本機寫入轉送需要 Aurora MySQL 3.04 版或更新版本，包括 8.4 版。

**Topics**
+ [啟用本機寫入轉送](aurora-mysql-write-forwarding-enabling.md)
+ [檢查資料庫叢集是否已啟用寫入轉送](#aurora-mysql-write-forwarding-describing)
+ [應用程式和 SQL 與寫入轉送的相容性](#aurora-mysql-write-forwarding-compatibility)
+ [寫入轉送的隔離層級](#aurora-mysql-write-forwarding-isolation)
+ [寫入轉送的讀取一致性](aurora-mysql-write-forwarding-consistency.md)
+ [使用寫入轉送執行多部分陳述式](#aurora-mysql-write-forwarding-multipart)
+ [具有寫入轉送的交易](#aurora-mysql-write-forwarding-txns)
+ [寫入轉送的組態參數](#aurora-mysql-write-forwarding-params)
+ [用於寫入轉送的 Amazon CloudWatch 指標和 Aurora MySQL 狀態變數](aurora-mysql-write-forwarding-cloudwatch.md)
+ [識別轉送的交易和查詢](#aurora-write-forwarding-processlist)

## 檢查資料庫叢集是否已啟用寫入轉送
<a name="aurora-mysql-write-forwarding-describing"></a>

若要確定您是否可以在資料庫叢集中使用寫入轉送，請確認該叢集的屬性 `LocalWriteForwardingStatus` 設定為 `enabled`。

在叢集詳細資訊頁面的 AWS 管理主控台**組態**索引標籤中，您會看到**啟用****本機僅供讀取複本寫入轉送**的狀態。

若要查看所有叢集的寫入轉送設定狀態，請執行下列 AWS CLI 命令。

**Example**  

```
aws rds describe-db-clusters \
--query '*[].{DBClusterIdentifier:DBClusterIdentifier,LocalWriteForwardingStatus:LocalWriteForwardingStatus}'

[
    {
        "LocalWriteForwardingStatus": "enabled",
        "DBClusterIdentifier": "write-forwarding-test-cluster-1"
    },
    {
        "LocalWriteForwardingStatus": "disabled",
        "DBClusterIdentifier": "write-forwarding-test-cluster-2"
    },
    {
        "LocalWriteForwardingStatus": "requested",
        "DBClusterIdentifier": "test-global-cluster-2"
    },
    {
        "LocalWriteForwardingStatus": "null",
        "DBClusterIdentifier": "aurora-mysql-v2-cluster"
    }
]
```

資料庫叢集可以具有以下值 `LocalWriteForwardingStatus`：
+ `disabled` – 寫入轉送已停用。
+ `disabling` – 寫入轉送正處於停用的過程。
+ `enabled` – 寫入轉送已啟用。
+ `enabling` – 寫入轉送正處於啟用的過程。
+ `null` – 寫入轉送不適用於此資料庫叢集。
+ `requested` – 已請求寫入轉送，但尚未作用中。

## 應用程式和 SQL 與寫入轉送的相容性
<a name="aurora-mysql-write-forwarding-compatibility"></a>

您可以使用以下類型的 SQL 陳述式搭配寫入轉送：
+ 資料操作語言 (DML) 陳述式，例如 `INSERT`、`DELETE` 和 `UPDATE`。這些陳述式的屬性有一些限制，您可以將這些屬性與寫入轉送搭配使用，如下所述。
+ `SELECT ... LOCK IN SHARE MODE` 和 `SELECT FOR UPDATE` 陳述式。
+ `PREPARE` 和 `EXECUTE` 陳述式。

當您在具有寫入轉送的資料庫叢集中使用某些陳述式時，系統不允許使用這些陳述式或這些陳述式可能會產生過時的結果。此外，不支援使用者定義的函數和使用者定義的程序。因此，資料庫叢集將 `EnableLocalWriteForwarding` 設定預設為停用。在啟用此功能之前，請檢查以確定您的應用程式的程式碼不受上述任何限制的影響。

下列限制適用於您與寫入轉送搭配使用的 SQL 陳述式。在某些情況下，您可以在啟用寫入轉送的資料庫叢集上使用陳述式。如果在工作階段中的寫入轉送啟用方式不是透過 `aurora_replica_read_consistency` 組態參數，則此方法有效。在不允許此方法時嘗試使用陳述式，因為寫入轉送導致，您將看到類似於下列的錯誤訊息：

```
ERROR 1235 (42000): This version of MySQL doesn't yet support '{{operation}} with write forwarding'.
```

**資料定義語言 (DDL)**  
連線到寫入器資料庫執行個體以執行 DDL 陳述式。您無法從讀取器資料庫執行個體執行。

**使用臨時資料表中的資料更新永久資料表**  
您可以在啟用寫入轉送的資料庫叢集上使用臨時資料表。但是，如果陳述式參照臨時資料表，則無法使用 DML 陳述式來修改永久資料表。例如，您不能使用從臨時資料表取得資料的 `INSERT ... SELECT` 陳述式。

**XA 交易**  
在工作階段中啟用寫入轉送時，您無法在資料庫叢集上使用下列陳述式。您可以在未啟用寫入轉送的資料庫叢集上，或在 `aurora_replica_read_consistency` 設定為空的工作階段中使用這些陳述式。在工作階段中啟用寫入轉送之前，請檢查您的程式碼是否使用這些陳述式。  

```
XA {START|BEGIN} xid [JOIN|RESUME]
XA END xid [SUSPEND [FOR MIGRATE]]
XA PREPARE xid
XA COMMIT xid [ONE PHASE]
XA ROLLBACK xid
XA RECOVER [CONVERT XID]
```

**永久資料表的 LOAD 陳述式**  
您無法在啟用寫入轉送的資料庫叢集上使用下列陳述式。  

```
LOAD DATA INFILE 'data.txt' INTO TABLE t1;
LOAD XML LOCAL INFILE 'test.xml' INTO TABLE t1;
```

**外掛程式陳述式**  
您無法在啟用寫入轉送的資料庫叢集上使用下列陳述式。  

```
INSTALL PLUGIN example SONAME 'ha_example.so';
UNINSTALL PLUGIN example;
```

**儲存點陳述式**  
在工作階段中啟用寫入轉送時，您無法在資料庫叢集上使用下列陳述式。您可以在未啟用寫入轉送的資料庫叢集上，或在 `aurora_replica_read_consistency` 設定為空的工作階段中使用這些陳述式。在工作階段中啟用寫入轉送之前，請檢查您的程式碼是否使用這些陳述式。  

```
SAVEPOINT t1_save;
ROLLBACK TO SAVEPOINT t1_save;
RELEASE SAVEPOINT t1_save;
```

## 寫入轉送的隔離層級
<a name="aurora-mysql-write-forwarding-isolation"></a>

在使用寫入轉送的工作階段中，您只能使用 `REPEATABLE READ` 隔離層級。雖然您也可以使用 Aurora 複本的 `READ COMMITTED` 隔離層級，但該隔離層級不適用於寫入轉送。如需 `REPEATABLE READ` 和 `READ COMMITTED` 隔離層級的相關資訊，請參閱 [Aurora MySQL 隔離層級](AuroraMySQL.Reference.IsolationLevels.md)。

## 使用寫入轉送執行多部分陳述式
<a name="aurora-mysql-write-forwarding-multipart"></a>

DML 陳述式可能包含多個部分，例如 `INSERT ... SELECT` 陳述式或 `DELETE ... WHERE` 陳述式。在這種情況下，系統會將整個陳述式轉送到寫入器資料庫執行個體並在該處執行陳述式。

## 具有寫入轉送的交易
<a name="aurora-mysql-write-forwarding-txns"></a>

如果交易存取模式設定為唯讀，則不會使用寫入轉送。您可以使用 `SET TRANSACTION` 陳述式或 `START TRANSACTION` 陳述式，來指定交易的存取模式。您也可以透過變更 [transaction\_read\_only](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_transaction_read_only) 工作階段變數的值，來指定交易存取模式。您只能在連線至已啟用寫入轉送的資料庫叢集時，變更此工作階段值。

如果長時間執行的交易經過很長一段時間內都未發出任何陳述式，則可能會超過閒置逾時期間。此期間的預設值為一分鐘。您可以將 `aurora_fwd_writer_idle_timeout` 參數設定為最多增加一天。超過閒置逾時的交易會被寫入器執行個體取消。您提交的下一個後續陳述式會收到逾時錯誤。然後 Aurora 會復原交易。

當寫入轉送變成無法使用時，可能會發生這種類型的錯誤。例如，如果您重新啟動資料庫叢集或停用寫入轉送，Aurora 就會取消任何使用寫入轉送的交易。

當叢集中使用本機寫入轉送的寫入器執行個體重新啟動時，使用本機寫入轉送的讀取器執行個體上任何作用中的轉送交易和查詢都會自動關閉。當寫入器執行個體再次可用之後，您可以重試這些交易。

## 寫入轉送的組態參數
<a name="aurora-mysql-write-forwarding-params"></a>

Aurora 資料庫參數群組包含寫入轉送功能的設定。下表列出了有關這些參數的詳細資訊，並在表格後面附有使用注意事項。


| 參數 | Scope (範圍) | 類型 | 預設值 | 有效值 | 
| --- | --- | --- | --- | --- | 
| aurora\_fwd\_writer\_idle\_timeout | 叢集 | 不帶正負號整數 | 60 | 1–86,400 | 
| aurora\_fwd\_writer\_max\_connections\_pct | 叢集 | 不帶正負號長整數 | 10 | 0–90 | 
| aurora\_replica\_read\_consistency | 叢集或執行個體 | 列舉 | '' (null) | EVENTUAL, SESSION, GLOBAL | 

若要控制傳入的寫入請求，請使用下列設定：
+ `aurora_fwd_writer_idle_timeout` – 寫入器資料庫執行個體在關閉讀取器執行個體之前，等待從讀取器執行個體轉送的連線上活動的秒數。如果工作階段在此期間之後仍處於閒置狀態，則 Aurora 會取消工作階段。
+ `aurora_fwd_writer_max_connections_pct` – 可在寫入器資料庫執行個體上，用來處理從讀取器執行個體轉送之查詢的資料庫連線上限。此上限的表示方式是寫入器的 `max_connections` 設定百分比。例如，如果 `max_connections` 是 800，且 `aurora_fwd_master_max_connections_pct` 或 `aurora_fwd_writer_max_connections_pct` 是 10，則寫入器允許最多 80 個同時轉送的工作階段。這些連線來自 `max_connections` 設定所管理的相同連線集區。

  此設定僅適用於已啟用寫入轉送功能的寫入器。如果您減少此值，現有的連線不會受到影響。Aurora 在嘗試從資料庫叢集建立新連線時，會考慮設定的新值。預設值為 10，代表該 `max_connections` 值的 10%。

**注意**  
因為 `aurora_fwd_writer_idle_timeout` 和 `aurora_fwd_writer_max_connections_pct`是資料庫叢集參數，所以每個叢集中的所有資料庫執行個體都有這些參數的相同值。

如需 `aurora_replica_read_consistency` 的相關資訊，請參閱 [寫入轉送的讀取一致性](aurora-mysql-write-forwarding-consistency.md)。

如需資料庫參數群組的詳細資訊，請參閱[Amazon Aurora 的參數群組](USER_WorkingWithParamGroups.md)。

## 識別轉送的交易和查詢
<a name="aurora-write-forwarding-processlist"></a>

您可以使用 `information_schema.aurora_forwarding_processlist` 資料表來識別轉送的交易和查詢。如需此資料表的詳細資訊，請參閱 [information\_schema.aurora\_forwarding\_processlist](AuroraMySQL.Reference.ISTables.md#AuroraMySQL.Reference.ISTables.aurora_forwarding_processlist)。

下列範例顯示寫入器資料庫執行個體上所有轉送的連線。

```
mysql> select * from information_schema.AURORA_FORWARDING_PROCESSLIST where IS_FORWARDED=1 order by REPLICA_SESSION_ID;

+-----+----------+--------------------+----------+---------+------+--------------+--------------------------------------------+--------------+--------------------+---------------------------------+----------------------+----------------+
| ID  | USER     | HOST               | DB       | COMMAND | TIME | STATE        | INFO                                       | IS_FORWARDED | REPLICA_SESSION_ID | REPLICA_INSTANCE_IDENTIFIER     | REPLICA_CLUSTER_NAME | REPLICA_REGION |
+-----+----------+--------------------+----------+---------+------+--------------+--------------------------------------------+--------------+--------------------+---------------------------------+---------------------------------------+
| 648 | myuser   | {{IP_address:port1}}   | sysbench | Query   |    0 | async commit | UPDATE sbtest58 SET k=k+1 WHERE id=4802579 |            1 |                637 | my-db-cluster-instance-2        | my-db-cluster        | us-west-2      |
| 650 | myuser   | {{IP_address:port2}}   | sysbench | Query   |    0 | async commit | UPDATE sbtest54 SET k=k+1 WHERE id=2503953 |            1 |                639 | my-db-cluster-instance-2        | my-db-cluster        | us-west-2      |
+-----+----------+--------------------+----------+---------+------+--------------+--------------------------------------------+--------------+--------------------+---------------------------------+----------------------+----------------+
```

在轉送讀取器資料庫執行個體上，您可以透過執行 `SHOW PROCESSLIST` 以查看與這些寫入器資料庫連線相關聯的執行緒。寫入器上 `REPLICA_SESSION_ID` 的值 637 和 639，與讀取器上的 `Id` 值相同。

```
mysql> select @@aurora_server_id;

+---------------------------------+
| @@aurora_server_id              |
+---------------------------------+
| my-db-cluster-instance-2        |
+---------------------------------+
1 row in set (0.00 sec)

mysql> show processlist;

+-----+----------+--------------------+----------+---------+------+--------------+---------------------------------------------+
| Id  | User     | Host               | db       | Command | Time | State        | Info                                        |
+-----+----------+--------------------+----------+---------+------+--------------+---------------------------------------------+
| 637 | myuser   | {{IP_address:port1}}   | sysbench | Query   |    0 | async commit | UPDATE sbtest12 SET k=k+1 WHERE id=4802579  |
| 639 | myuser   | {{IP_address:port2}}   | sysbench | Query   |    0 | async commit | UPDATE sbtest61 SET k=k+1 WHERE id=2503953  |
+-----+----------+--------------------+----------+---------+------+--------------+---------------------------------------------+
12 rows in set (0.00 sec)
```