首批通过分布式安全可靠测评,为关键业务系统打造
强读分区表路由
更新时间:2026-04-14 17:41:09
本文介绍什么是强读分区表路由,并结合示例讲解如何配置强读分区表路由。
背景介绍
在 OceanBase 数据库中,分区(Partition)是数据存储的基本单元。当您创建表时,就会存在表和分区 (Partition) 的映射。如果创建的是非分区表,一张表仅对应一个分区 (Partition) ,如果创建的是分区表,一张表可能会对应多个分区 (Partition) 。
目前 OceanBase 数据库未实现分区 (Partition) 的合并和分裂。假设客户端请求某表的 P0 分区,P0 分区在 OBServer0 节点和 OBServer2 节点上,ODP 却将请求路由到 OBServer1 节点,因为 OBServer1 节点不存在该分区数据,所以 ODP 会将请求再次路由到 OBServer0 节点或 OBServer2 节点,从而产生远程计划(Remote Plan)。而 ODP 若保存着自 P0 分区到 OBServer0 节点和自 P0 分区到 OBServer2 节点的映射,将会保证将请求路由到存在该分区数据的 OBServer 节点,避免远程计划。
路由时仅路由到分区所在的 OBServer 节点还不够,还需要知道分区的主备信息,每个分区在 OceanBase 数据库中存在主副本(Leader)和备副本(Follower),他们分布在不同的 OBServer 节点上面,假设 OBServer0 节点为主副本、OBServer2 节点为备副本,此时一个强读请求被路由到了备副本,备副本会将请求路由至主副本,产生远程计划。ODP 可以区分强读/弱读请求,将强读请求发往主副本,避免远程计划。
说明
在 OceanBase 数据库中,有 Local 计划、Remote 计划和 Distributed 计划三种表路由。Local 计划、Remote 计划均为单分区的路由。ODP 的作用就是尽量消除 Remote 计划,将路由尽可能地变为 Local 计划。如果表路由类型为 Remote 计划的 SQL 过多,说明该 ODP 的路由可能存在问题(可通过查看 oceanbase.GV$OB_SQL_AUDIT 视图中 plan_type 字段来确认表路由类型)。表路由的详细介绍可参见 OceanBase 数据库文档 ODP 表路由 一文。
使用方法
当客户端强读分区表时,可在 SQL 语句中提供分区键值、表达式或分区名,ODP 会将分区键值解析为分区 ID,之后通过分区 ID 查找并路由到对应副本位置。
SQL 语句中提供分区键列值,例如 T0 表分区键为 C1,查询语句可以为
SELECT * FROM T0 WHERE C1 = xxxx;。SQL 语句中提供分区键列表达式,例如 T0 表分区键为 C1,查询语句可以为
SELECT * FROM T0 WHERE C1 = ABS(xxxx);。SQL 语句中提供分区名称, 例如 T0 表一级分区名称有 P0、P1、 P2,二级分区名称有 SP0、SP1、SP2,查询语句可以为
INSERT INTO T0 PARTITION(P0SSP2) VALUES(xxxx);。
注意
指定分区名称的语法为
SELECT/UPDATE/INSERT ... table_name PARTITION(partition_name[Ssubpartition_name]),分区表的一级分区默认名称为 P0、P1、P2 等,二级分区默认名称为 SP0、SP1、SP2 等。使用指定分区名称路由时如果不指定二级分区名称,则删去语句中标识指定二级分区名的前缀字符
S。
本节通过三个示例分别介绍如何使用强读分区表路由。
示例一:SQL 语句中提供分区键值
登录 OceanBase 数据库,执行如下命令创建分区表。
obclient [test]> CREATE TABLE T0(C1 INT) PARTITION BY HASH(C1) PARTITIONS 8;为将要执行的 SQL 语句提供分区键值。
obclient [test]> SELECT /* +READ_CONSISTENCY(STRONG) */ * FROM T0 WHERE C1=123;使用 EXPLAIN ROUTE 命令查看 ODP 路由选取的过程。
obclient [test]> EXPLAIN ROUTE SELECT /* +READ_CONSISTENCY(STRONG) */ * FROM T0 WHERE C1=123\G输出如下,ODP 将 SQL 语句路由至分区主副本。
*************************** 1. row *************************** ... Route Plan ----------------- > SQL_PARSE:{cmd:"COM_QUERY", table:"T0"} > ROUTE_INFO:{route_info_type:"USE_PARTITION_LOCATION_LOOKUP"} > LOCATION_CACHE_LOOKUP:{mode:"oceanbase"} > TABLE_ENTRY_LOOKUP_DONE:{table:"T0", table_id:500084, partition_num:8, table_type:"USER TABLE", entry_from_remote:false} > PARTITION_ID_CALC_START:{} > EXPR_PARSE:{col_val:"C1=123"} > RESOLVE_EXPR:{part_range:"[123 ; 123]"} > RESOLVE_TOKEN:{token_type:"TOKEN_INT_VAL", resolve:{"BIGINT":123}, token:"123"} > CALC_PARTITION_ID:{part_description:"partition by hash(INT(binary)) partitions 8"} > PARTITION_ID_CALC_DONE:{partition_id:200065, level:1, partitions:"(p3)"} > 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"}
示例二:SQL 语句中提供分区键表达式
登录 OceanBase 数据库,执行如下命令创建分区表。
obclient [test]> CREATE TABLE T0(C1 INT) PARTITION BY HASH(C1) PARTITIONS 8;为将要执行的 SQL 语句提供分区键表达式。
obclient [test]> SELECT /* +READ_CONSISTENCY(STRONG) */ * FROM T0 WHERE C1=ABS(123);使用 EXPLAIN ROUTE 命令查看 ODP 路由选取的过程。
obclient [test]> EXPLAIN ROUTE SELECT /* +READ_CONSISTENCY(STRONG) */ * FROM T0 WHERE C1=123\G输出如下,ODP 完成 ABS() 函数计算后,路由至分区主副本。
*************************** 1. row *************************** ... Route Plan ----------------- > SQL_PARSE:{cmd:"COM_QUERY", table:"T0"} > ROUTE_INFO:{route_info_type:"USE_PARTITION_LOCATION_LOOKUP"} > LOCATION_CACHE_LOOKUP:{mode:"oceanbase"} > TABLE_ENTRY_LOOKUP_DONE:{table:"T0", table_id:500084, partition_num:8, table_type:"USER TABLE", entry_from_remote:false} > PARTITION_ID_CALC_START:{} > EXPR_PARSE:{col_val:"C1=123"} > RESOLVE_EXPR:{part_range:"[123 ; 123]"} > RESOLVE_TOKEN:{token_type:"TOKEN_INT_VAL", resolve:{"BIGINT":123}, token:"123"} > CALC_PARTITION_ID:{part_description:"partition by hash(INT(binary)) partitions 8"} > PARTITION_ID_CALC_DONE:{partition_id:200065, level:1, partitions:"(p3)"} > 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"}
示例三:SQL 语句中提供分区名称
登录 OceanBase 数据库,执行如下命令创建分区表。
obclient [test]> CREATE TABLE T0(C1 INT) PARTITION BY HASH(C1) PARTITIONS 8;创建分区表时未指定分区名称,将会使用默认分区名称。
为将要执行的 SQL 语句提供分区名称。
obclient [test]> SELECT /* +READ_CONSISTENCY(STRONG) */ * FROM T0 PARTITION(P1) WHERE C1=123;使用 EXPLAIN ROUTE 命令查看 ODP 路由选取的过程。
obclient [test]> EXPLAIN ROUTE SELECT * FROM T0 PARTITION(p1) WHERE C1=123\G输出如下,ODP 将 SQL 语句路由至 P0 分区。
Trans Current Query:"EXPLAIN ROUTE SELECT * FROM T0 PARTITION(p1) WHERE C1=123" Route Prompts ----------------- > ROUTE_INFO [INFO] Will route to partition server or routed by route policy > PARTITION_ID_CALC_DONE [INFO] Will route to specified partition name(p1) Route Plan ----------------- > SQL_PARSE:{cmd:"COM_QUERY", table:"T0"} > ROUTE_INFO:{route_info_type:"USE_PARTITION_LOCATION_LOOKUP"} > LOCATION_CACHE_LOOKUP:{mode:"oceanbase"} > TABLE_ENTRY_LOOKUP_DONE:{table:"T0", table_id:500084, partition_num:8, table_type:"USER TABLE", entry_from_remote:false} > PARTITION_ID_CALC_DONE:{partition_id:200063, level:1, part_name:"p1"} > PARTITION_ENTRY_LOOKUP_DONE:{leader:"10.10.10.3:50111"} > ROUTE_POLICY:{chosen_route_type:"ROUTE_TYPE_LEADER"} > CONGESTION_CONTROL:{svr_addr:"10.10.10.3:50111"}Will route to specified partition name(p1)说明 ODP 将请求路由至语句中指定的分区名的分区。