### 5.1.18 客户端会话状态的服务器跟踪

[](<>)[](<>)

MySQL 服务器实现了几个会话状态跟踪器。客户端可以使这些跟踪器接收其会话状态更改的通知。

-   [会话状态跟踪器的用途](session-state-tracking.html#session-state-tracking-uses)

-   [可用的会话状态跟踪器](session-state-tracking.html#session-state-tracking-notifications)

-   [C API 会话状态跟踪器支持](session-state-tracking.html#session-state-tracking-capi-support)

-   [测试套件会话状态跟踪器支持](session-state-tracking.html#session-state-tracking-test-suite-support)

#### 会话状态跟踪器的用途

会话状态跟踪器具有以下用途：

-   便于会话迁移。

-   方便交易切换。

    跟踪器机制为 MySQL 连接器和客户端应用程序提供了一种方法来确定是否有任何会话上下文可用于允许会话从一个服务器迁移到另一个服务器。（要在负载均衡的环境中更改会话，在决定是否可以进行切换时，需要检测是否存在要考虑的会话状态。）

    跟踪器机制允许应用程序知道何时可以将事务从一个会话移动到另一个会话。事务状态跟踪实现了这一点，这对于希望将事务从繁忙的服务器移动到负载较少的服务器的应用程序很有用。例如，管理客户端连接池的负载平衡连接器可以在池中的可用会话之间移动事务。

    但是，会话切换不能在任意时间进行。如果会话处于已完成读取或写入的事务的中间，则切换到不同的会话意味着原始会话上的事务回滚。仅当事务尚未在其中执行任何读取或写入时，才必须进行会话切换。

    何时可以合理切换事务的示例：

-   之后立马[`开始交易`](commit.html)

-   后[`承诺与链`](commit.html)

    除了了解事务状态之外，了解事务特性也很有用，以便在事务移动到不同会话时使用相同的特性。与此目的相关的特征如下：


```
READ ONLY
READ WRITE
ISOLATION LEVEL
WITH CONSISTENT SNAPSHOT
```

#### 可用的会话状态跟踪器

为了支持会话跟踪活动，通知可用于这些类型的客户端会话状态信息：

-   对客户端会话状态的这些属性的更改：

    -   默认架构（数据库）。

    -   系统变量的会话特定值。

    -   用户定义的变量。

    -   临时表。

    -   准备好的陈述。

        这[`session_track_state_change`](server-system-variables.html#sysvar_session_track_state_change)系统变量控制这个跟踪器。

    [](<>)[](<>)

-   更改默认架构名称。这[`session_track_schema`](server-system-variables.html#sysvar_session_track_schema)系统变量控制这个跟踪器。

    [](<>)[](<>)

-   更改系统变量的会话值。这[`session_track_system_variables`](server-system-variables.html#sysvar_session_track_system_variables)系统变量控制这个跟踪器。

    [](<>)[](<>)

-   可用的 GTID。这[`session_track_gtids`](server-system-variables.html#sysvar_session_track_gtids)系统变量控制这个跟踪器。

    [](<>)[](<>)

-   有关事务状态和特征的信息。这[`session_track_transaction_info`](server-system-variables.html#sysvar_session_track_transaction_info)系统变量控制这个跟踪器。

    有关跟踪器相关系统变量的描述，请参见[第 5.1.8 节，“服务器系统变量”](server-system-variables.html).这些系统变量允许控制发生哪些更改通知，但不提供访问通知信息的方法。通知发生在 MySQL 客户端/服务器协议中，该协议在 OK 数据包中包含跟踪器信息，以便可以检测到会话状态更改。

#### C API 会话状态跟踪器支持

为了使客户端应用程序能够从服务器返回的 OK 数据包中提取状态更改信息，MySQL C API 提供了一对函数：

-   [`mysql_session_track_get_first()`](https://dev.mysql.com/doc/c-api/8.0/en/mysql-session-track-get-first.html)获取从服务器接收到的状态更改信息的第一部分。看[mysql\_会议\_追踪\_得到\_第一的（）](https://dev.mysql.com/doc/c-api/8.0/en/mysql-session-track-get-first.html).

    [](<>)

-   [`mysql_session_track_get_next()`](https://dev.mysql.com/doc/c-api/8.0/en/mysql-session-track-get-next.html)获取从服务器接收到的任何剩余状态更改信息。成功调用后[`mysql_session_track_get_first()`](https://dev.mysql.com/doc/c-api/8.0/en/mysql-session-track-get-first.html)，只要返回成功就重复调用这个函数。看[mysql\_会议\_追踪\_得到\_下一个（）](https://dev.mysql.com/doc/c-api/8.0/en/mysql-session-track-get-next.html).

    [](<>)

#### 测试套件会话状态跟踪器支持

[](<>)[](<>)[](<>)[](<>)[](<>)[](<>)[](<>)[](<>)[](<>)[](<>)[](<>)[](<>)

这**mysql测试**程序有`disable_session_track_info`和`enable_session_track_info`控制会话跟踪器通知是否发生的命令。您可以使用这些命令从命令行查看 SQL 语句产生的通知。假设一个文件`测试脚本`包含以下内容**mysql测试**脚本：

```
DROP TABLE IF EXISTS test.t1;
CREATE TABLE test.t1 (i INT, f FLOAT);
--enable_session_track_info
SET @@SESSION.session_track_schema=ON;
SET @@SESSION.session_track_system_variables='*';
SET @@SESSION.session_track_state_change=ON;
USE information_schema;
SET NAMES 'utf8mb4';
SET @@SESSION.session_track_transaction_info='CHARACTERISTICS';
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SET TRANSACTION READ WRITE;
START TRANSACTION;
SELECT 1;
INSERT INTO test.t1 () VALUES();
INSERT INTO test.t1 () VALUES(1, RAND());
COMMIT;
```

按如下方式运行脚本以查看启用的跟踪器提供的信息。对于描述`追踪器：`显示的信息**mysql测试**对于各种跟踪器，请参阅[mysql\_会议\_追踪\_得到\_第一的（）](https://dev.mysql.com/doc/c-api/8.0/en/mysql-session-track-get-first.html).

```
$> mysqltest < testscript
DROP TABLE IF EXISTS test.t1;
CREATE TABLE test.t1 (i INT, f FLOAT);
SET @@SESSION.session_track_schema=ON;
SET @@SESSION.session_track_system_variables='*';
-- Tracker : SESSION_TRACK_SYSTEM_VARIABLES
-- session_track_system_variables
-- *

SET @@SESSION.session_track_state_change=ON;
-- Tracker : SESSION_TRACK_SYSTEM_VARIABLES
-- session_track_state_change
-- ON

USE information_schema;
-- Tracker : SESSION_TRACK_SCHEMA
-- information_schema

-- Tracker : SESSION_TRACK_STATE_CHANGE
-- 1

SET NAMES 'utf8mb4';
-- Tracker : SESSION_TRACK_SYSTEM_VARIABLES
-- character_set_client
-- utf8mb4
-- character_set_connection
-- utf8mb4
-- character_set_results
-- utf8mb4

-- Tracker : SESSION_TRACK_STATE_CHANGE
-- 1

SET @@SESSION.session_track_transaction_info='CHARACTERISTICS';
-- Tracker : SESSION_TRACK_SYSTEM_VARIABLES
-- session_track_transaction_info
-- CHARACTERISTICS

-- Tracker : SESSION_TRACK_STATE_CHANGE
-- 1

-- Tracker : SESSION_TRACK_TRANSACTION_CHARACTERISTICS
--

-- Tracker : SESSION_TRACK_TRANSACTION_STATE
-- ________

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-- Tracker : SESSION_TRACK_TRANSACTION_CHARACTERISTICS
-- SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

SET TRANSACTION READ WRITE;
-- Tracker : SESSION_TRACK_TRANSACTION_CHARACTERISTICS
-- SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; SET TRANSACTION READ WRITE;

START TRANSACTION;
-- Tracker : SESSION_TRACK_TRANSACTION_CHARACTERISTICS
-- SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; START TRANSACTION READ WRITE;

-- Tracker : SESSION_TRACK_TRANSACTION_STATE
-- T_______

SELECT 1;
1
1
-- Tracker : SESSION_TRACK_TRANSACTION_STATE
-- T_____S_

INSERT INTO test.t1 () VALUES();
-- Tracker : SESSION_TRACK_TRANSACTION_STATE
-- T___W_S_

INSERT INTO test.t1 () VALUES(1, RAND());
-- Tracker : SESSION_TRACK_TRANSACTION_STATE
-- T___WsS_

COMMIT;
-- Tracker : SESSION_TRACK_TRANSACTION_CHARACTERISTICS
--

-- Tracker : SESSION_TRACK_TRANSACTION_STATE
-- ________

ok
```

之前的[`开始交易`](commit.html)声明，二[`设置交易`](set-transaction.html)执行为下一个事务设置隔离级别和访问模式特征的语句。这`SESSION_TRACK_TRANSACTION_CHARACTERISTICS`value 表示已经设置的那些下一个事务值。

继[`犯罪`](commit.html)结束交易的声明，`SESSION_TRACK_TRANSACTION_CHARACTERISTICS`值报告为空。这表明在事务开始之前设置的下一个事务特征已被重置，并且会话默认值适用。要跟踪对这些会话默认值的更改，请跟踪[`交易隔离`](server-system-variables.html#sysvar_transaction_isolation)和[`transaction_read_only`](server-system-variables.html#sysvar_transaction_read_only)系统变量。

要查看有关 GTID 的信息，请启用`SESSION_TRACK_GTIDS`跟踪器使用[`session_track_gtids`](server-system-variables.html#sysvar_session_track_gtids)系统系统变量。
