

# Amazon Aurora MySQL 中的事务超时
<a name="AuroraMySQL.TransactionTimeout"></a>

`aurora_transaction_timeout` 参数可设置事务的最大持续时间。此参数有助于防止长时间运行的事务（活动或空闲）阻塞 [InnoDB 清除操作](https://dev.mysql.com/doc/refman/8.4/en/glossary.html#glos_purge)，从而避免引发性能问题。此参数适用于 Aurora MySQL 版本 8.4.8 及更高版本。

**Topics**
+ [参数详细信息](#AuroraMySQL.TransactionTimeout.parameter-details)
+ [超时行为](#AuroraMySQL.TransactionTimeout.behavior)
+ [示例](#AuroraMySQL.TransactionTimeout.examples)
+ [关键说明](#AuroraMySQL.TransactionTimeout.key-notes)
+ [客户端错误](#AuroraMySQL.TransactionTimeout.client-error)
+ [错误日志](#AuroraMySQL.TransactionTimeout.error-log)
+ [监控事务超时](#AuroraMySQL.TransactionTimeout.monitoring)
+ [与其他超时的交互](#AuroraMySQL.TransactionTimeout.interaction)

## 参数详细信息
<a name="AuroraMySQL.TransactionTimeout.parameter-details"></a>

`aurora_transaction_timeout` 参数会终止任何超过指定持续时间的 InnoDB 事务，包括只读事务。以秒为单位指定该值。值为零（默认值）将禁用超时。

下表汇总了参数详细信息。


| 属性 | 值 | 
| --- | --- | 
| 名称 | aurora\_transaction\_timeout | 
| 范围 | 会话、全局 | 
| 默认值 | 0（禁用） | 
| 单位 | 秒 | 
| 动态 | 是，仅应用于新的 InnoDB 事务 | 

您可以在集群、实例或会话级别设置 `aurora_transaction_timeout` 参数。有关使用参数组的更多信息，请参阅[Amazon Aurora 的参数组](USER_WorkingWithParamGroups.md)。

## 超时行为
<a name="AuroraMySQL.TransactionTimeout.behavior"></a>

`aurora_transaction_timeout` 参数适用于执行 DML 语句的 InnoDB 事务，包括只读事务。除 `CREATE TABLE .. AS SELECT`（CTAS）和 `LOAD DATA` 之外，所有其他[隐式提交语句](https://dev.mysql.com/doc/refman/8.4/en/implicit-commit.html)均不受超时限制。在第一个 InnoDB 语句运行时，捕获超时值。该值在所属事务的生命周期内保持不变。

当超时到期后，结果取决于事务状态：
+ 如果事务中存在活动查询，则查询会中断，并回滚事务。连接仍然可用。
+ 如果不存在活动查询（即事务处于空闲状态），则连接将会终止。

## 示例
<a name="AuroraMySQL.TransactionTimeout.examples"></a>

以下示例显示了在不同事务场景下，计时器的启动时机。

### 显式事务
<a name="AuroraMySQL.TransactionTimeout.examples.explicit"></a>

```
BEGIN;                    -- Does NOT start InnoDB transaction. No timer.
SELECT * FROM t1;         -- Starts InnoDB transaction. Timer starts HERE (at statement 2).
```

计时器从语句 2（第一个 InnoDB 语句）开始计时。

### autocommit=0
<a name="AuroraMySQL.TransactionTimeout.examples.autocommit"></a>

```
SET SESSION autocommit=0;  -- No transaction yet
SELECT * FROM t1;          -- Starts InnoDB transaction. Timer starts HERE.
INSERT INTO t1 ...;        -- Same transaction, timer still running from step 2.
```

计时器从语句 2（禁用自动提交后的第一个 InnoDB 语句）开始计时。

### 存储过程
<a name="AuroraMySQL.TransactionTimeout.examples.stored-procs"></a>

存储过程在调用方的事务上下文中运行。如果调用方已经存在活动的 InnoDB 事务，则在调用该过程之前计时器便已启动。如果该过程是第一个访问 InnoDB 的操作，则计时器从该过程内的第一个 InnoDB 语句开始计时。

```
BEGIN;
CALL my_proc();  -- If my_proc() does SELECT/INSERT, timer starts at that first InnoDB statement inside the proc
```

## 关键说明
<a name="AuroraMySQL.TransactionTimeout.key-notes"></a>
+ **超时值在事务开始时捕获**：超时值在第一个 InnoDB 语句执行时捕获。在事务执行过程中更改 `aurora_transaction_timeout` 后，更改将在下一个事务中生效，而不会影响当前事务。不会引发任何警告。
+ **XA PREPARED 事务不受限制**：已准备好的事务不受 `aurora_transaction_timeout` 约束。
+ **写入转发会话不受事务超时限制**：启用写入转发后，任何包含转发语句的语句或事务均不受 `aurora_transaction_timeout` 约束。同一会话中不包含转发语句的后续事务会像往常一样受到超时的影响。要控制转发事务的空闲超时，您可以使用 `aurora_fwd_writer_idle_timeout` 参数。有关更多信息，请参阅 [Aurora MySQL 中写入转发的配置参数](aurora-global-database-write-forwarding-ams.md#aurora-global-database-write-forwarding-params-ams)。
+ **谨慎设置过高的超时值**：在回滚长时间运行的事务时，回滚所需的时间可能会比原始数据更改操作长数倍。终止数据库进程没有任何用处，因为回滚会在服务器启动时重新开始。选择一个能够在工作负载需求与回滚成本之间取得平衡的超时值。有关更多信息，请参阅 MySQL 文档中的 [Optimizing InnoDB Transaction Management](https://dev.mysql.com/doc/refman/8.4/en/optimizing-innodb-transaction-management.html)。

## 客户端错误
<a name="AuroraMySQL.TransactionTimeout.client-error"></a>

当包含活动查询的事务超出超时时间时，客户端会收到以下错误：

```
ERROR 63952 (40001): Transaction exceeded maximum allowed duration of <N> seconds and was rolled back. See aurora_transaction_timeout for configuring this behavior.
```

当空闲事务超出超时时间时，后续查询会收到 MySQL“服务器已断开连接”这样的错误。有关更多信息，请参阅 MySQL 文档中的 [MySQL server has gone away](https://dev.mysql.com/doc/refman/8.4/en/gone-away.html)。

## 错误日志
<a name="AuroraMySQL.TransactionTimeout.error-log"></a>

发生事务超时时，数据库错误日志中会写入一条信息性消息：

```
[Note] Transaction breached timeout threshold and will be rolled back, if still in progress. If idle, the connection will be aborted. Check response for confirmation. connection_id: 4821, trx_id: 28193, user: app_user, timeout: 5 seconds, duration: 7 seconds
```

**注意**  
此日志消息仅用于诊断目的。以客户端响应作为事务超时的明确指标。

## 监控事务超时
<a name="AuroraMySQL.TransactionTimeout.monitoring"></a>

使用 `Aurora_transaction_timeouts` 状态变量跟踪自数据库实例重启以来发生超时的事务数量。

```
SHOW GLOBAL STATUS LIKE 'Aurora_transaction_timeouts';
```

启用 `performance_schema` 后，超时错误 (`ER_AURORA_TRANSACTION_TIMEOUT_ERROR`) 也会记录在 `performance_schema.events_errors_summary_global_by_error` 及相关表中。请注意，只有活动事务超时才会使此计数器递增；空闲事务超时会直接终止连接，而不会引发 `ER_AURORA_TRANSACTION_TIMEOUT_ERROR` 错误。

## 与其他超时的交互
<a name="AuroraMySQL.TransactionTimeout.interaction"></a>

`aurora_transaction_timeout` 与现有超时参数结合使用。如果事务的持续时间超过已配置的 `aurora_transaction_timeout`，则无论其他超时设置如何，该事务都将会终止。其他超时机制是否也会回滚事务，取决于各自的实施方式。有关这些参数的详细信息，请参阅 MySQL 文档。