<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>OceanBase on 飞鸿踏雪泥</title><link>https://dyhes.github.io/tags/oceanbase/</link><description>Recent content in OceanBase on 飞鸿踏雪泥</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Wed, 26 Feb 2025 17:14:04 +0800</lastBuildDate><atom:link href="https://dyhes.github.io/tags/oceanbase/index.xml" rel="self" type="application/rss+xml"/><item><title>【OceanBase】Basics</title><link>https://dyhes.github.io/p/oceanbasebasics/</link><pubDate>Tue, 18 Nov 2025 00:00:00 +0000</pubDate><guid>https://dyhes.github.io/p/oceanbasebasics/</guid><description>&lt;h2 id="系统架构"&gt;系统架构
&lt;/h2&gt;&lt;p&gt;OceanBase 数据库采用无共享（Shared-Nothing）分布式集群架构，各个节点之间完全对等，每个节点都有自己的 SQL 引擎、存储引擎、事务引擎，运行在普通 PC 服务器组成的集群之上，具备高可扩展性、高可用性、高性能、低成本、与主流数据库高兼容等核心特性。&lt;/p&gt;
&lt;p&gt;在 OceanBase 数据库中，一个表的数据可以按照某种划分规则水平拆分为多个分片，每个分片叫做一个&lt;strong&gt;表分区，简称分区（Partition）&lt;/strong&gt;。某行数据属于且只属于一个分区。分区的规则由用户在&lt;strong&gt;建表的时候指定&lt;/strong&gt;，包括 Hash、Range、List 等类型的分区，同时还支持二级分区。例如，交易库中的订单表，可以先按照用户 ID 划分为若干个一级分区，再按照月份把每个一级分区划分为若干个二级分区。&lt;strong&gt;对于二级分区表，二级分区的每个分区是一个物理分区，而一级分区只是逻辑概念&lt;/strong&gt;。一个表的若干个分区可以分布在&lt;strong&gt;一个可用区内的多个节点上&lt;/strong&gt;。每个物理分区有一个用于&lt;strong&gt;存储数据的存储层对象，叫做 Tablet&lt;/strong&gt;，用于存储有序的数据记录。&lt;/p&gt;
&lt;p&gt;当用户对 Tablet 中的记录进行修改时，为了保证数据的持久化，需要记录 Redo 日志到 Tablet 对应的日志流（Log Stream，LS）中。每个日志流服务了其所在节点上的多个 Tablet。为了能够保护数据，并在节点发生故障时不中断服务，每个日志流及其所属的 Tablet 有多个副本。一般来说，&lt;strong&gt;多个副本分散在多个不同的可用区&lt;/strong&gt;里。多个副本中有且仅有一个副本接受修改操作，叫做主副本（Leader），其他副本叫做从副本（Follower）。主从副本之间通过基于 Multi-Paxos 的分布式共识协议实现了副本之间数据的一致性。当主副本所在节点发生故障时，一个从副本会被选举为新的主副本并继续提供服务。&lt;/p&gt;
&lt;p&gt;为了实现 OceanBase 数据库对应用程序&lt;strong&gt;屏蔽内部分区和副本分布&lt;/strong&gt;等细节，使应用访问分布式数据库像访问单机数据库一样简单，我们提供了 OceanBase 数据库代理 &lt;strong&gt;ODP&lt;/strong&gt;（OceanBase Database Proxy，又称 &lt;strong&gt;OBProxy&lt;/strong&gt;）服务。应用程序并不会直接与 OceanBase 数据库节点建立连接，而是连接 ODP，然后由 ODP 转发 SQL 请求到合适的 OceanBase 数据库节点。ODP 是&lt;strong&gt;无状态&lt;/strong&gt;的服务，多个 ODP 节点通过&lt;strong&gt;网络负载均衡&lt;/strong&gt;（例如，SLB）对应用提供统一的网络地址。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/observer-enterprise/V4.3.1/oceanbase-cluster-system-architecture.png"
loading="lazy"
alt="OceanBase 集群架构图"
&gt;&lt;/p&gt;
&lt;p&gt;OceanBase 数据库的服务器上会运行一个名为 &lt;strong&gt;observer&lt;/strong&gt; 的单进程程序作为数据库的运行实例，使用本地的文件存储数据和事务 Redo 日志。&lt;/p&gt;
&lt;p&gt;OceanBase 集群的部署需要配置可用区（Zone），&lt;strong&gt;每个可用区由若干个服务器组成&lt;/strong&gt;。可用区是一个逻辑概念，表示集群内具有相似硬件可用性的一组节点，它在不同的部署模式下代表不同的含义。例如，当整个集群部署在同一个数据中心（IDC）内的时候，一个可用区的节点可以属于同一个机架，同一个交换机等。当集群分布在多个数据中心的时候，每个可用区可以对应于一个数据中心。&lt;/p&gt;
&lt;p&gt;OceanBase 数据库内置&lt;strong&gt;多租户特性&lt;/strong&gt;，每个租户相当于一个独立的数据库实例，一个租户能够在租户级别设置本租户的分布式部署方式。各租户之间的 CPU、内存和 IO 等资源相互隔离。&lt;/p&gt;
&lt;p&gt;OceanBase 集群的数据库实例内部由不同的组件相互协作，这些组件从底层向上由多租户层、存储层、复制层、均衡层、事务层、SQL 层、接入层组成。&lt;/p&gt;
&lt;h3 id="多租户层"&gt;多租户层
&lt;/h3&gt;&lt;p&gt;为了简化大规模部署&lt;strong&gt;多个业务数据库的管理&lt;/strong&gt;并降低资源成本，OceanBase 数据库提供了独特的多租户特性。在一个 OceanBase 集群内，可以创建很多个互相之间隔离的数据库&amp;quot;实例&amp;quot;，叫做一个租户。&lt;strong&gt;从应用程序的视角来看，每个租户等同于一个独立的数据库实例&lt;/strong&gt;。不仅如此，&lt;strong&gt;每个租户可以选择 MySQL 或 Oracle 兼容模式&lt;/strong&gt;。应用连接到 MySQL 租户后，可以在租户下创建用户、Database，与一个独立的 MySQL 库的使用体验一致。同样的，应用连接到 Oracle 租户后，可以在租户下创建 Schema、管理角色等，与一个独立的 Oracle 库的使用体验一致。一个新的集群初始化之后，就会存在一个特殊的名为 sys 的租户，叫做&lt;strong&gt;系统租户&lt;/strong&gt;。系统租户中保存了集群的元数据，是一个 MySQL 兼容模式的租户。&lt;/p&gt;
&lt;p&gt;为了&lt;strong&gt;隔离&lt;/strong&gt;租户的资源，每个 observer 进程内可以有多个属于不同租户的虚拟容器，叫做&lt;strong&gt;资源单元（UNIT）&lt;/strong&gt;。资源单元包括 CPU 和内存资源。&lt;strong&gt;每个租户在多个节点&lt;/strong&gt;上的资源单元组成一个&lt;strong&gt;资源池&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id="表组"&gt;表组
&lt;/h2&gt;&lt;p&gt;表组（Table Group）是一个逻辑概念，表示一组表的集合。默认情况下，不同表之间的数据是随机分布的，没有直接关系。通过定义表组，可以&lt;strong&gt;控制一组表在物理存储上的邻近关系&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id="分区"&gt;分区
&lt;/h2&gt;&lt;p&gt;OceanBase 数据库可以把普通的表的数据&lt;strong&gt;按照一定的规则划分到不同的区块&lt;/strong&gt;内，同一区块的数据物理上存储在一起。这种划分区块的表叫做分区表，其中的每一个区块称作分区。OceanBase 数据库的 MySQL 模式中，单个表最多支持创建的分区个数为由租户级配置项 &lt;code&gt;max_partition_num&lt;/code&gt; 控制，默认为 8192 个。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/observer-enterprise/V4.2.1/database-object-management/partition.png"
loading="lazy"
alt="分区"
&gt;&lt;/p&gt;
&lt;p&gt;上图分区表的每个分区还能按照一定的规则再拆分成多个分区，这种分区表叫做二级分区表。&lt;/p&gt;
&lt;p&gt;数据表中每一行中用于计算这一行属于哪一个分区的列的集合叫做分区键，&lt;strong&gt;分区键必须是主键或唯一键的子集，只要有主键就必须是主键的子集&lt;/strong&gt;。由分区键构成的用于计算这一行属于哪一个分区的表达式叫做&lt;strong&gt;分区表达式&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="range-分区"&gt;Range 分区
&lt;/h3&gt;&lt;h2 id="索引"&gt;索引
&lt;/h2&gt;&lt;p&gt;索引也叫二级索引，是一种可选的表结构。OceanBase 数据库采用的是聚集索引表模型，对于用户指定的主键，系统会自动生成主键索引，而&lt;strong&gt;对于用户创建的其他索引，则是二级索引&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="函数索引"&gt;函数索引
&lt;/h3&gt;&lt;p&gt;基于表中一列或多列的值进行计算后的结果建立的索引称为函数索引。函数索引是一种优化技术，使用函数索引可以在查询时快速定位匹配的函数值，从而避免重复计算，提高查询效率。&lt;/p&gt;
&lt;p&gt;在 OceanBase 数据库的 MySQL 模式中，对函数索引的表达式进行了限制，禁止部分系统函数的表达式作为函数索引，具体的函数列表请参见 &lt;a class="link" href="https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001576030" target="_blank" rel="noopener"
&gt;函数索引支持的系统函数列表&lt;/a&gt; 和 &lt;a class="link" href="https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001576028" target="_blank" rel="noopener"
&gt;函数索引不支持的系统函数列表&lt;/a&gt;。&lt;/p&gt;</description></item></channel></rss>