---
title: "ODP 表路由 - OceanBase 数据库 V4.2.1 | OceanBase 文档中心"
description: ODP 表路由 本章节介绍 ODP 的表路由机制。 在 OceanBase 数据库中，Partition 是数据存储的基本单元。当我们创建表时，就会存在表和 Partition 的映射。如果是非分区表，一张表仅对应一个 Partition，如果是分区表，一张表可能会对应多个 Partition。目前 OceanBas…
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

文档反馈![](https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*P8CuR4UJ_FkAAAAAAAAAAAAADiGDAQ/original) OceanBase 数据库分布式版 - V 4.2.1 LTS

# ODP 表路由

更新时间：2026-04-16 00:11:36

[编辑](https://github.com/oceanbase/oceanbase-doc/edit/V4.2.1/zh-CN/700.reference/1200.database-proxy/700.route-management/100.odp-table-routing.md)  

本章节介绍 ODP 的表路由机制。

在 OceanBase 数据库中，Partition 是数据存储的基本单元。当我们创建表时，就会存在表和 Partition 的映射。如果是非分区表，一张表仅对应一个 Partition，如果是分区表，一张表可能会对应多个 Partition。目前 OceanBase 数据库未实现 Partition 的合并和分裂。

在 OceanBase 数据库中，有 Local 计划、Remote 计划和 Distributed 计划三种表路由。Local 计划、Remote 计划均为单分区的路由。ODP 的作用就是尽量消除 Remote 计划，将路由尽可能的变为 Local 计划。如果表路由类型为 Remote 计划的 SQL 过多，说明该 ODP 的路由可能存在问题（可通过查看 `oceanbase.GV$OB_SQL_AUDIT` 视图中 `plan_type` 字段来确认）。

## 非分区表路由

在 ODP 中保存了 Partition 和 OBServer_addr 的映射缓存，Partition 通过 SQL Parser 获取表名，非分区表通过表名去 Location Cache 中获取分区信息；如果是访问分区表且语句中提供了分区键值，则还会获取其中的分区键值，然后通过表名从 Location Cache 获取分区元数据，然后再通过分区键值以及分区元数据计算出分区 ID，从而获取 Partition 所在节点的 IP。

存在如下三种情况：

- Location Cache 中不存在，访问 OBServer 节点的 `__all_virtual_proxy_schema` 表拉取。
 - Location Cache 中存在并可用，直接使用。
 - Location Cache 中存在但不可用，从 Location Cache 中去除并重新拉取。

更多 Location Cache 相关的说明，请参见 [租户内路由](https://www.oceanbase.com/docs/enterprise-odp-enterprise-cn-10000000000982783)。

## 分区表路由

和非分区表一样，在 ODP 中保存了 Partition 和 OBServer_addr 的映射缓存，Partition 通过 SQL Parser 功能解析获取表名。相比非分区表，分区表额外增加了一个分区 ID 信息，根据表名和分区 ID 去 Location Cache 中获取 Partition 所在 OBServer 的 IP。

分区 ID 通过 SQL 语句获取，来源往往是 where 子句的表达式、insert 语句 values 值。需要保证能获取到 `a = xxx`，其中 `a` 为分区键，`xxx` 为常量。示例如下：

```sql
obclient> CREATE TABLE t1(c1 int, c2 int) PARTITION BY hash(c1) partitions 5;
obclient> UPDATE t1 SET c2 = 3 WHERE c1 = 5;

```

这里提取到 `c1 = 5`，通过这个信息可以计算到影响到的分区 ID，将 SQL 转发给对应分区所在 OBServer 节点即可。

ODP 如果计算不出分区 ID，那么就无法拉取准确的路由。可以在 obproxy.log 日志文件中，搜索 "calculate partition id" 查看是否计算成功。示例如下：

```shell
[root@ocp-deploy-obnorpm2-bfc89744b-qsfkz log]# grep "calculate partition id" obproxy.log
[2021-10-28 17:18:18.552825] DEBUG [PROXY] ob_mysql_route.cpp:577 [73979][Y0-7FB3C9D07A80] [lt=10] [dc=0] succ to calculate partition id(part_id_=1)
[2021-10-28 17:18:31.045191] INFO  [PROXY] ob_mysql_route.cpp:575 [73979][Y0-7FB3C9D07A80] [lt=17] [dc=0] fail to calculate partition id, just use tenant server(tmp_ret=-4002)

```

有关分区表的相关介绍，请参见 [管理分区](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000220228)。

## ODP 依赖的 OceanBase 数据库内部表

路由的准确性，除了与 ODP 本身有关，还依赖于从 OceanBase 数据库内部表中获取到正确信息。如下为 ODP 所依赖的 OceanBase 数据库内部表：

- `__all_virtual_proxy_schema`：用于保存分区与其所在机器的对应关系信息，也有 Partition 的部分相关信息。
 - `__all_virtual_proxy_partition_info`：保存分区表相关分区信息。
 - `__all_virtual_proxy_partition`：保存一级分区信息。
 - `__all_virtual_proxy_sub_partition`：保存二级分区信息。

 上一篇 下一篇 ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
