OceanBase 数据库代理(OceanBase Database Proxy,简称 ODP,又称 OBProxy)是 OceanBase 数据库专用的代理服务器,使用 ODP 可以屏蔽后端 OceanBase 集群分布式带来的复杂性,让访问分布式数据库像访问单机数据库一样简单。
ODP 的核心特性是最佳路由,基本逻辑是 ODP 接收用户发出的 SQL 请求,并将 SQL 请求转发至最佳目标 OBServer 节点,最后将执行结果返回给用户。ODP 支持丰富的路由功能,以满足用户在不同场景下的路由需求,实现最佳路由效果。本文主要介绍常用的路由功能及配置方式,帮助用户在业务实践中正确配置路由策略及快速排查路由问题。
一、常用路由功能与配置
ODP 提供了丰富的路由功能,用户可以根据实际需要,设置对应的配置项来控制路由策略。
(一)强制路由
强制路由是指用户无法控制的路由行为,由 ODP 决定是否强制路由,主要包含以下情况:
🚩 指定 IP 路由:可通过 target_db_server 配置项进行指定,ODP 会将 SQL 请求直接路由到指定的 OBServer 节点,此方式具有最高优先级。示例如下:
ALTER PROXYCONFIG SET target_db_server = '127.0.0.1:2993;10.10.10.1:50109';上述示例中, ODP 收到的所有请求都会路由到 127.0.0.1:2993 节点。如果 127.0.0.1:2993 节点不存在或者故障,则路由到 10.10.10.1:50109 节点。关于指定 IP 路由的更多信息,请点击下方链接或长按二维码,参考指定 IP 路由。
https://www.oceanbase.com/docs/common-odp-doc-cn-1000000000755689

扫码参考指定 IP 路由
🚩 指定 Zone 路由:可通过 proxy_primary_zone_name 配置项进行指定,ODP 会将请求直接路由到指定的 Zone。示例如下:
ALTER PROXYCONFIG SET proxy_primary_zone_name='z2';上述示例中,ODP 收到的所有请求都会路由到 z2。关于指定 Zone 路由的更多信息,请点击下方链接或长按二维码,参考强读 Primary Zone 路由。
https://www.oceanbase.com/docs/common-odp-doc-cn-1000000000755698

扫码参考强读 Primary Zone 路由
🚩 特定场景强制路由:
✅ 非分布式事务路由:事务内语句强制路由至事务开启的 OBServer 节点。
✅ 会话级临时表路由:对会话级临时表进行查询时,会强制路由至第一次查询临时表的 OBServer 节点。
✅ CURSOR/PIECES 路由:客户端使用 CURSOR/PIECES 流式获取/上传数据时,所有请求会强制路由至同一 OBServer 节点。
说明:
❗ 指定 IP 路由和指定 Zone 路由,是强制性的路由,不会区分是否强读,适用于不关心 Leader 位置,需要路由到指定节点的场景。
❗ 如果是交易支付等强读业务,希望路由到 Leader 的场景,需要确保强制路由配置项没有设置,避免产生大量远程路由、二次路由等问题。
(二)强读路由
强读路由主要分为以下情况:
1、分区表路由:
ODP 将 SQL 请求中的分区键值或表达式、分区名等条件解析为分区 ID,通过分区 ID 查找到分区的副本位置,将请求路由到 Leader 副本。
🚩 根据分区键值或表达式计算路由,示例如下:
CREATE TABLE T(C1 INT) PARTITION BY HASH(C1) PARTITIONS 8;SELECT * FROM T WHERE C1=123;SELECT * FROM T WHERE C1=ABS(123);
上述示例中,ODP 将查询请求路由到对应分区 Leader 节点。
🚩 根据分区名计算路由,示例如下:
CREATE TABLE T(C1 INT) PARTITION BY KEY(C1) PARTITIONS 8;SELECT * FROM T PARTITION(P1);
上述示例中,ODP 将查询请求路由到 P1 分区的 Leader 节点。
说明:
❗ OceanBase 数据库有 Local 计划、Remote 计划和 Distributed 计划三种表路由。
❗ Local 计划、Remote 计划均为单分区的路由。ODP 的作用是尽量消除 Remote 计划,将路由尽可能的变为 Local 计划。
❗ 如果表路由类型为 Remote 计划的 SQL 过多,说明该 ODP 的路由可能存在问题,需要排查。
关于分区表路由的更多信息,请点击下方链接或长按二维码,参考强读分区表路由。
https://www.oceanbase.com/docs/common-odp-doc-cn-1000000000755693

扫码参考强读分区表路由
2、全局索引表路由:
使用全局索引表路由时,ODP 会将 SQL 语句中提供的索引值作为分区键来计算路由。强读分区表时,在为分区表创建全局索引,并在后续的读写中使用索引值作为查询条件的情况下,可使用 ODP 的全局索引路由功能来提升查询效率。
可通过配置 enable_reroute 和 enable_index_route,将语句中提供的索引值作为分区键来计算路由,示例如下:
ALTER PROXYCONFIG SET enable_reroute=true;ALTER PROXYCONFIG SET enable_index_route = true;CREATE TABLE T(C1 INT,C2 INT) PARTITION BY HASH(C1) PARTITIONS 8;CREATE INDEX INDEX1 ON T(C2);SELECT * FROM T WHERE C2=2;SELECT * FROM T WHERE C2=2;
上述示例中,第一次使用索引查询,将随机路由,OBServer 节点将返回索引表的 Leader,ODP 会构建语句到索引表名称 [SELECT * FROM T WHERE C2=2;] -> [T_INDEX] 的映射然后进行二次路由,直接获取 T_INDEX 表的映射,计算路由。
关于全局索引表路由的更多信息,请点击下方链接或长按二维码,参考强读全局索引表路由。
https://www.oceanbase.com/docs/common-odp-doc-cn-1000000000755695

扫码参考强读全局索引表路由
3、复制表路由:
复制表是 OceanBase 数据库中的一种特殊表结构,支持在任意一个副本读取数据的最新修改,适合于对写入频率要求较低,读延时和读负载均衡要求较高的场景。
ODP 对复制表采用随机路由的策略,示例如下:
CREATE TABLE T_DUP(C1 INT) DUPLICATE_SCOPE = 'cluster';SELECT * FROM T_DUP WHERE C1=123;
上述示例中,ODP 将查询请求随机路由到 T_DUP 表的任意副本。关于复制表路由的更多信息,请点击下方链接或长按二维码,参考强读复制表路由。
https://www.oceanbase.com/docs/common-odp-doc-cn-1000000000755690

扫码参考强读复制表路由
4、计算失败后的路由:
当 ODP 无法获取 SQL 请求中的表名或者无法通过 SQL 请求中的条件计算出准确的分区位置信息时,无法准确的强读请求路由到 Leader。此时有三种处理策略:
🚩 按照租户 Primary Zone 路由:enable_primary_zone=True,将请求路由到租户的 Primary Zone。
🚩 复用上一次的会话路由:enable_cached_server =true,将请求路由到上一个OBServer 会话。
🚩 随机路由:enable_primary_zone=false 且 enable_cached_server =false,将请求随机路由。
示例如下:
场景一:enable_primary_zone=false && enable_cached_server =true
CREATE TABLE T(C1 INT,C2 INT) PARTITION BY HASH(C1) PARTITIONS 8;SELECT * FROM T WHERE C1=1; # 请求准确路由到 server1SELECT * FROM T WHERE C2=1; # 无分区条件,无法计算路由,直接将请求路由到上一个会话 server1SELECT * FROM T WHERE C1=2; # 请求准确路由到 server2SELECT * FROM T WHERE C2=2; # 无分区条件,无法计算路由,直接将请求路由到上一个会话 server2
场景二:enable_primary_zone=true && enable_cached_server =true && leader在server1
SELECT * FROM T WHERE C1=1; # 请求准确路由到 server1SELECT * FROM T WHERE C2=1; # 无分区条件,无法计算路由,直接将请求路由到 server1SELECT * FROM T WHERE C1=2; # 请求准确路由到 server1SELECT * FROM T WHERE C2=2; # 无分区条件,无法计算路由,直接将请求路由到server1
说明:
对于生产环境和测试环境,一般情况下,建议 enable_cached_server 设置为 false。
如果需要分析 ODP 的路由策略,可以使用 EXPLAIN ROUTE executable sql 查看 ODP 路由选取过程。
(三)事务路由
事务路由分两种场景:
🚩 分布式事务路由:事务内的 SQL 请求准确路由到 Leader 节点。
说明:
OceanBase 数据库 V4.1.0 版本开始支持分布式事务路由。
可通过配置 enable_ob_protocol_v2 = true 和 enable_transaction_INTernal_routing = true 来开启分布式路由,示例如下:
ALTER PROXYCONFIG SET enable_ob_protocol_v2 = true;ALTER PROXYCONFIG SET enable_transaction_INTernal_routing = true;CREATE TABLE T1(C1 INT,C2 INT) PARTITION BY HASH(C1) PARTITIONS 8;CREATE TABLE T2(C1 INT,C2 INT) PARTITION BY HASH(C1) PARTITIONS 8;BEGIN;INSERT INTO T1 VALUES(1,1);# 路由到server1INSERT INTO T2 VALUES(11,11);# 路由到server2SELECT * FROM T1 WHERE C1=1;# 路由到server1SELECT * FROM T2 WHERE C1=11;# 路由到server2COMMIT;
上述示例中,事务内的请求都能够准确路由到对应的 Leader。关于分布式路由的更多信息,请点击下方链接或长按二维码,参考分布式事务路由。
https://www.oceanbase.com/docs/common-odp-doc-cn-1000000000755691

扫码参考分布式事务路由
🚩 非分布式事务路由:事务内 SQL 请求强制路由至事务开启 OBServer 节点。
示例如下:
ALTER PROXYCONFIG SET enable_ob_protocol_v2 = false;ALTER PROXYCONFIG SET enable_transaction_INTernal_routing = false;CREATE TABLE T1(C1 INT,C2 INT) PARTITION BY HASH(C1) PARTITIONS 8;CREATE TABLE T2(C1 INT,C2 INT) PARTITION BY HASH(C1) PARTITIONS 8;BEGIN;INSERT INTO T1 VALUES(1,1);# 路由到server1INSERT INTO T2 VALUES(11,11);# 路由到server1SELECT * FROM T1 WHERE C1=1;# 路由到server1SELECT * FROM T2 WHERE C1=11;# 路由到server1COMMIT;
上述示例中,事务内的请求都路由到第一条 INSERT 的路由节点 server1。
(四)弱读路由
对于弱读请求,ODP 提供两种路由策略:
🚩 LDC 路由:给 OceanBase 集群的每个 Zone 设置地区(Region)属性和机房(IDC)属性,并给 ODP 指定机房(IDC)配置项,ODP 将弱读请求按“同机房>同地区>异地”的优先级顺序进行 OBServer 节点的选取。
可通过配置项 proxy_idc_name 控制 LDC 路由,示例如下:
alter system modify zone "z1" set region = "region1";alter system modify zone "z1" set idc = "idc1";alter system modify zone "z2" set region = "region1";alter system modify zone "z2" set idc = "idc2";alter proxyconfig set proxy_idc_name='idc1';CREATE TABLE T(C1 INT,C2 INT) PARTITION BY HASH(C1) PARTITIONS 8;SELECT /*+READ_CONSISTENCY(WEAK) */ * FROM T;
上述示例中,ODP 会将弱读请求路由到同 IDC 的 z1。
🚩 随机路由:ODP 将弱读请求随机路由到 Leader 或者 Follower 副本,副本优先级由 proxy_route_policy 控制。对应路由策略为:FOLLOWER_FIRST、FOLLOWER_ONLY、UNMERGE_FOLLOWER_FIRST。
本文内容以 ODP V4.3.0 为例,示例如下:
CREATE TABLE T(C1 INT,C2 INT) PARTITION BY HASH(C1) PARTITIONS 8;# T 表的 leader 在 z1,follower 在 z2、z3
场景一:alter proxyconfig set proxy_route_policy='';
SELECT /*+READ_CONSISTENCY(WEAK) */ * FROM T;# ODP 在 z1、z2、z3 三个副本随机选择副本转发弱读请求
场景二:alter proxyconfig set proxy_route_policy='FOLLOWER_FIRST';
SELECT /*+READ_CONSISTENCY(WEAK) */ * FROM T;# ODP 优先选择 z2、z3 转发弱读请求,如果 z2、z3 都不可用,则转发到 z1
场景三:alter proxyconfig set proxy_route_policy='FOLLOWER_ONLY';
SELECT /*+READ_CONSISTENCY(WEAK) */ * FROM T;# ODP 只选择 z2、z3 转发弱读请求,如果 z2、z3 都不可用,则请求报错
场景四:alter proxyconfig set proxy_route_policy='UNMERGE_FOLLOWER_FIRST';
SELECT /*+READ_CONSISTENCY(WEAK) */ * FROM T;# ODP 优先选择没在做合并的 z2、z3 转发弱读请求
LDC 路由的优先级高于随机路由,ODP 在选择副本时,先检查 LDC 路由,再走随机路由策略。
说明:
弱读的路由策略 LDC 路由和随机路由,同样适用于计算分区失败的强读路由请求。
二、典型场景
在不同的业务场景,需要综合考虑路由策略配置及优先级,进行合理配置,实现指定的路由目标。下面以两个典型路由场景为例,介绍路由功能的应用实践。
(一)读写分离
1、路由场景
OLTP 与 OLAP 业务混合负载场景下,希望将交易类请求发送到 TP 副本,将分析型请求发送到 AP 副本,TP、AP 类业务请求需要部署独立的 ODP,接收 AP 请求的 ODP 需要支持将业务的强读请求转换为弱读,并只发送到 AP 副本。部署架构如图:

🚩 路由配置实践
✅ 接收 AP 请求的 ODP:
alter proxyconfig set obproxy_read_consistency='1'; # 设置弱读alter proxyconfig set proxy_primary_zone_name='zone_4'; # 设置路由目标副本
注意!
设置之前,需确保没有设置过指定 IP 路由的配置。可通过 show proxyconfig like 'target_db_server'; 命令进行检查。
✅ 接受 TP 请求的 ODP:
ALTER PROXYCONFIG SET enable_cached_server = false;ALTER PROXYCONFIG SET enable_primary_zone = true;
对交易类请求,需要准确路由到分区 Leader,如果无法准确计算,则尽量路由到租户的 Primary Zone,减少远程路由。
ODP 将交易类请求只发往 ZONE_1、ZONE_2、ZONE_3 的对应 Leader 副本。
注意!
设置之前,需确保没有设置过指定 IP 路由及指定 Zone 路由。可通过 show proxyconfig like 'target_db_server'; 和 show proxyconfig like 'proxy_primary_zone_name'; 命令进行检查。
2、只读副本
🚩 路由场景:
OceanBase 数据库支持的副本类型,除了全功能型副本,还有只读型副本,简称 R 副本。R 副本只提供读能力,只能作为日志流的 Follower 副本。实际业务中,可以将实时性要求不高的分析类读请求发送到R副本,减轻 Leader 副本的压力。
🚩 路由配置实践:
✅ 设置弱读:alter proxyconfig set obproxy_read_consistency='1';
✅ 设置 LDC 策略:只读副本同 IDC 的 ODP 和 OBServer 节点设置为相同 IDC。
✅ 设置路由策略:alter proxyconfig set proxy_route_policy='FOLLOWER_ONLY';
三、案例分析
某云客户在使用 OceanBase 数据库时,通过租户的只读地址执行了一项大规模查询操作,但该查询操作并未按照预期访问到只读副本,而是访问到了主副本,影响了主副本的正常业务运行。
1、原因分析
经排查,发现在 OceanBase 数据库的路由配置中,启用了两个关键参数:enable_cached_server 和 enable_primary_zone。
当 enable_primary_zone 和 enable_cached_server 设置为 true 时,路由逻辑如下:
✅ enable_primary_zone=true:用户登录时,会将登录请求发往租户的主副本。
✅ enable_cached_server=true: 在 ODP 没有解析出表名、表分区计算失败等情况下,请求会复用前一个连接,也就是登录时选择的主副本,这就导致请求无法根据只读地址信息对路由做优化,造成后续的所有请求都发往了主副本。
2、解决方法
关闭 enable_cached_server 和 enable_primary_zone。
关于 ODP 路由的更多信息,请点击下方链接或长按二维码,参考 ODP 路由功能。
https://www.oceanbase.com/docs/common-odp-doc-cn-1000000000755434

扫码参考 ODP 路由功能
关于 OceanBase 最佳实践内容,将会持续发布和更新,想了解更多和更新内容,可以点击下方前往 OceanBase 官网。
https://www.oceanbase.com/docs/common-best-practices-1000000001489641




