首批通过分布式安全可靠测评,为关键业务系统打造
会话状态同步
更新时间:2026-04-14 17:41:09
本文介绍 ODP 会话状态同步的作用及同步过程。
状态同步介绍
在连接管理的原理介绍中了解到,当客户端通过 ODP 和 OceanBase 数据库建立连接时,整个链路如下所示。一个客户端连接对应多个服务端连接,要保证执行结果的正确性,就要求多个服务端连接的 session 状态是一致的。

Client 和 ODP 之间存在一个会话 Session0,该会话是客户端直接感知并可见的会话,如果 Session0 的会话状态未同步到 Session1/Session2/Session3,执行 SQL 语句时可能会导致报错。
ODP 通过版本号机制解决了状态同步的问题,实现了 database、session variables、last_insert_id 和 ps prepare 语句的状态同步,保证功能的正确性。Session0 会话的状态(比如系统变量、用户变量、事务状态)都将被 ODP 同步到 Session1/Session2/Session3,以保证 OBServer 节点能够根据会话状态做出正确的行为。
举例说明状态不同步将会导致的问题,假设目前集群 AUTOCOMMIT = 1,执行如下 SQL 命令。
set autocommit = 0;
insert into t1 values(1);
insert into t2 values(2);
执行过程如下:
set autocommit=0;发给 OBServer1 节点insert into t1 values(1);发给 OBServer1 节点进行连接切换,
insert into t2 values(2);发给 OBServer2 节点

对于第三条 SQL(insert into t2 values(2);),ODP 和 OBServer2 节点的连接并未同步连接状态 autocommit=0,这样就可能导致第三条语句执行完成后在 OBServer2 节点提交事务,而 OBServer1 节点还处于事务中。正确的步骤是 ODP 在给 OBServer2 节点发送 INSERT SQL 前,先同步 autocommit 变量的值。
状态同步过程
本节通过修改会话级别的系统变量来展示 ODP 如何进行状态同步。
客户端发起与 ODP 的连接(会话 Session0),ODP 选择集群中的一个 OBServer 节点建连(会话 Session1)。
假设目前集群
AUTOCOMMIT = 1,客户端发送命令SET AUTOCOMMIT=0,修改会话变量 AUTOCOMMIT,ODP 在 Session0 中记录 AUTOCOMMIT 被修改,之后通过 Session1 转发给 OBServer1 节点。
若 Client 发送了一条 SQL 语句,想要访问的数据在 OBServer2 节点,ODP 收到 SQL 语句解析后将和 OBServer2 节点建连(会话 Session2)。

Session0 会话中的系统变量
AUTOCOMMIT=0,而 Session2 中系统变量仍然为默认值AUTOCOMMIT=1,此时 ODP 会将 Session0 中的系统变量AUTOCOMMIT=0覆盖到 Session2 中,以保证同一个客户端的会话状态与服务端会话状态保持一致。