MySQL服务器实现了几个会话状态跟踪器。客户端可以使这些跟踪器能够接收会话状态更改的通知。
1 会话状态跟踪器的用途
会话状态跟踪器具有以下用途:
- 以便于会话迁移。
- 便于交易切换。
跟踪器机制为MySQL连接器和客户端应用程序提供了一种方法,以确定是否有任何会话上下文可用于允许从一台服务器到另一台服务器的会话迁移。(要在负载平衡的环境中更改会话,在决定是否可以进行切换时,有必要检测是否存在需要考虑的会话状态。)
跟踪器机制允许应用程序知道何时可以将事务从一个会话移动到另一个会话。事务状态跟踪可以实现这一点,这对于希望将事务从繁忙的服务器移动到负载较低的服务器的应用程序非常有用。例如,管理客户端连接池的负载平衡连接器可以在池中的可用会话之间移动事务。
但是,会话切换不能在任意时间进行。如果会话处于已完成读取或写入的事务的中间,则切换到不同的会话意味着原始会话上的事务回滚。只有当事务中尚未执行任何读取或写入操作时,才能进行会话切换。
交易可能合理切换的示例:
除了了解事务状态之外,还可以了解事务特性,以便在事务移动到不同会话时使用相同的特性。以下特征与此相关:
READ ONLY READ WRITE ISOLATION LEVEL WITH CONSISTENT SNAPSHOT
2 可用的会话状态跟踪器
为了支持会话跟踪活动,可以为以下类型的客户端会话状态信息提供通知:
(1)对客户端会话状态的这些属性的更改:
- 默认架构(数据库)。
- 系统变量的会话特定值。
- 用户定义的变量。
- 临时表格。
- 准备好的发言。
session_track_state_change系统变量控制该跟踪器。
(2)更改为默认架构名称。session_track_schema系统变量控制该跟踪器。
(3)更改系统变量的会话值。session_track_system_variables系统变量控制该跟踪器。需要SENSITIVE_VARIABLES_OBSERVER权限来跟踪敏感系统变量值的更改。
(4)可用的GTID。session_track_gtids系统变量控制该跟踪器。
(5)有关事务状态和特性的信息。session_track_transaction_info系统变量控制该跟踪器。
这些系统变量允许控制哪些更改通知发生,但不提供访问通知信息的方法。通知发生在MySQL客户端/服务器协议中,该协议在OK数据包中包含跟踪器信息,以便检测会话状态的更改。
3 C API会话状态跟踪器支持
为了使客户端应用程序能够从服务器返回的OK数据包中提取状态变化信息,MySQL C API提供了一对功能:
- mysql_session_track_get_first()获取从服务器接收的状态更改信息的第一部分。
- mysql_session_track_get_next()获取从服务器接收的任何剩余状态更改信息。在成功调用mysql_session_track_get_first()之后,只要返回成功,就重复调用此函数。
4 测试套件会话状态跟踪器支持
mysqltest程序具有disable_session_track_info和enable_session\utrack_ininfo命令,用于控制是否发生会话跟踪器通知。您可以使用这些命令从命令行查看SQL语句产生的通知。假设一个文件testscript包含以下mysqltest脚本:
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;
按如下方式运行脚本,以查看启用的跟踪器提供的信息。。
$> 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
在START TRANSACTION语句之前,执行两个SET TRANSACTION声明,为下一个事务设置隔离级别和访问模式特征。SESSION_TRACK_TRANSACTION_CHARACTERISTICS值指示已设置的下一个事务值。
在结束事务的COMMIT语句之后,SESSION_TRACK_transaction_CHARACTERISTICS值报告为空。这表示在事务开始之前设置的下一个事务特性已经重置,并且应用会话默认值。要跟踪对这些会话默认值的更改,请跟踪transaction_inisolation和transaction_read_only系统变量的会话值。
要查看有关GTID的信息,请使用SESSION_TRACK_GTIDs系统变量启用SESSION_TRACK_GTIDs跟踪器。