首批通过分布式安全可靠测评,为关键业务系统打造
分布式事务路由
更新时间:2026-04-14 17:41:09
OceanBase 数据库自 V4.1.0 起支持事务在多个节点执行,不受事务开启节点限制。当事务内出现多条读写语句,且其访问的数据不在同一分区时,ODP 可以将事务内的请求发往其数据所在的机器,而非事务开启节点,此功能可以有效的减少 OceanBase 数据库生成远程计划,提升事务性能。
事务路由节点选择
事务路由的执行节点分为协调者和参与者两种节点。
协调者节点:事务的开启节点负责执行会影响事务状态的非 DML 语句,比如 BEGIN、START TRANSACTION、COMMIT、ROLLBACK 等。
参与者节点:负责执行事务中不会影响事务状态的 DML 语句。
ODP 包含的简单的 SQL Parser,能够解析出 SQL 语句是否为 DML 语句。ODP 解析出一条语句属于 DML 语句之后,会通过表路由或者 LDC 路由,将语句路由到合适的节点,被路由到的节点即成为事务的参与者节点,事务中第一条语句的执行节点即为事务的协调者节点。
开启方法
您可通过配置 ODP 配置项开启分布式事务路由,涉及配置项及配置方法如下所示。
ALTER PROXYCONFIG SET enable_ob_protocol_v2 = true;
ALTER PROXYCONFIG SET enable_transaction_internal_routing = true;
注意
仅 root@proxysys 账号和 root@sys 账号可执行
ALTER PROXYCONFIG命令。开启分布式事务路由后,
ob_trx_idle_timeout的配置将失效。ob_trx_idle_timeout的详细介绍可参见 ob_trx_idle_timeout
示例
执行如下命令开启 OceanBase 2.0 协议和分布式事务路由开关。
ALTER PROXYCONFIG SET enable_ob_protocol_v2 = true; ALTER PROXYCONFIG SET enable_transaction_internal_routing = true;执行如下命令创建表,开启事务并进行一次查询
创建表
obclient [test]> CREATE TABLE T0(C1 INT) PARTITION BY HASH(C1) PARTITIONS 8;开启事务
obclient [test]> BEGIN;执行一次查询
obclient [test]> SELECT * FROM T0 WHERE C1=0;查询后的下一条语句将正常进行分区路由,不受事务首条语句限制。
使用 EXPLAIN ROUTE 命令查看 ODP 路由选取过程
obclient [test]> EXPLAIN ROUTE INSERT INTO T0 VALUES(7)\G输出如下。
*************************** 1. row *************************** Route Plan: Trans First Query:"SELECT * FROM T0 WHERE C1=0" Trans Current Query:"EXPLAIN ROUTE INSERT INTO T0 VALUES(7)" Route Prompts ----------------- > ROUTE_INFO [INFO] Will route to partition server or routed by route policy Route Plan ----------------- > SQL_PARSE:{cmd:"COM_QUERY", table:"T0"} > ROUTE_INFO:{route_info_type:"USE_PARTITION_LOCATION_LOOKUP", in_transaction:true} > LOCATION_CACHE_LOOKUP:{mode:"oceanbase"} > TABLE_ENTRY_LOOKUP_DONE:{table:"T0", table_id:500021, partition_num:8, table_type:"USER TABLE", entry_from_remote:false} > PARTITION_ID_CALC_START:{} > EXPR_PARSE:{col_val:"=7"} > RESOLVE_EXPR:{part_range:"[7 ; 7]"} > RESOLVE_TOKEN:{token_type:"TOKEN_INT_VAL", resolve:{"BIGINT":7}, token:"7"} > CALC_PARTITION_ID:{part_description:"partition by hash(INT(binary)) partitions 8"} > PARTITION_ID_CALC_DONE:{partition_id:200012, level:1, partitions:"(p7)"} > PARTITION_ENTRY_LOOKUP_DONE:{leader:"10.10.10.1:50109", entry_from_remote:false} > ROUTE_POLICY:{chosen_route_type:"ROUTE_TYPE_LEADER"} > CONGESTION_CONTROL:{svr_addr:"10.10.10.1:50109"}