在OceanBase的日常使用中,分区设计一直是一道不低的门槛。一张表的数据量从GB级增长到TB级,如果分区划分不当,数据可能全部堆在一个OB Server上,造成热点和负载不均。如果为了均衡而划分过细,元数据膨胀和分区裁剪效率下降又会带来新的问题。更棘手的是,业务是动态的:今天按照公司ID做Key分区恰好均衡,明天新增了按公司范围扫描的批量查询,Key分区在范围扫描时不得不让所有分区都参与,IO和网络放大随之而来。
自动分区要解决的正是这个矛盾:让数据库根据数据量自己决定什么时候分裂、分裂到哪里,用户只需要设定一个大小阈值,剩下的交给系统。OceanBase桌面版的出现,让这个特性第一次变得触手可及:不需要搭一套分布式集群,一台Windows笔记本上装好WSL 2,半小时之内就能把一个自动分区表跑起来,亲眼看到分区从无到有、从少到多的过程。
这篇文章沿着一次完整的桌面版体验展开,先拆解自动分区的核心机制和关键语法,再记录从安装桌面版到实际触发分裂的操作过程,然后分析这个特性在真实业务中改变了什么,最后讨论它的边界和工程上的注意事项。
第一章 自动分区到底在解决什么问题
1.1 手动分区的两难
在自动分区出现之前,分区设计本质上是一个预测问题:你需要根据对当前数据分布和未来业务变化的判断,预先划定分区的边界或数量。预测准确,分区均衡,查询和写入都能获得分布式架构的红利;预测失准,要么分区过大导致热点,要么分区过多导致元数据和调度开销膨胀。
以一个主键为(公司ID,员工ID)的表为例。如果业务以点查为主,按照(公司ID,员工ID)做Key分区是合理的,数据量大致均衡,点查也能精确路由到单个分区。但一旦业务新增了按公司ID范围扫描的批量处理需求,Key分区就暴露了短板:范围扫描需要让所有分区都参与,IO放大和网络放大让批量处理的性能显著劣化。如果改为Range分区,边界怎么划又成了新问题,因为每个公司的员工数量是未知且动态变化的。
这个两难的根源在于,手动分区把数据分布的决策锁定在了建表的那一刻,而数据分布是持续演化的。自动分区的思路是把决策从建表时推迟到运行时,让数据库根据实际的数据量来决定何时分裂,从而绕开了预测问题。
1.2 自动分区的运作逻辑
自动分区的核心机制可以概括为阈值触发和按需分裂。在建表时或者租户级别设定一个大小阈值,当某个分区的数据量增长到超过这个阈值时,系统在后台自动将该分区拆分为更小的分区,使每个分区的数据量回落到阈值以下。分裂过程对业务是透明的,普通DML和查询不会被阻塞,分裂本身消耗的资源也较少。
这个设计的关键在于,它把分区的粒度与数据量的增长解耦了。小表不需要预先划分,因为它远远达不到阈值;大表会在增长过程中自动获得与其体量匹配的分区数量。用户不再需要回答"这张表应该分多少个区"这个问题,只需要回答"每个分区最大允许多大"这个问题。后者的难度远低于前者,因为它是一个容量规划问题,而不是一个数据分布预测问题。
第二章 关键语法与参数:SIZE子句和auto_split_tablet_size
2.1 建表时的SIZE子句
自动分区的语法入口是建表语句中的SIZE子句。一个典型的自动分区表定义如下:
sql
CREATE TABLE auto_part_t (
id BIGINT NOT NULL,
gmt_create TIMESTAMP NOT NULL,
data VARCHAR(256),
PRIMARY KEY (id)
) PARTITION BY RANGE (id) SIZE('10GB');
这里PARTITION BY RANGE (id)指定了预分区键。当触发自动分区时,系统会将id作为实际的分区键。SIZE('10GB')是可选的,指定了该表的分裂阈值。如果不写SIZE子句,系统会读取租户级别的配置项auto_split_tablet_size作为默认阈值。
SIZE的取值支持unlimited,表示分裂阈值无限制,分区永远不会分裂。这在某些希望完全控制分区行为的场景中有用,但也意味着关闭了自动分区的核心能力。
2.2 租户级参数的控制
auto_split_tablet_size是租户级别的配置项,控制该租户下所有未显式指定SIZE的表在开启自动分区后的默认分裂阈值。这个参数的默认值在不同版本之间存在差异:较早版本中默认值为128MB,从V4.4.1开始改为2GB。128MB对于桌面版体验来说是一个偏小的值,意味着一张几GB的测试表很快就能触发多次分裂,适合观察行为;2GB则更接近生产环境的合理起点,避免分区数量过快膨胀。
修改租户级阈值的语法是:
sql
ALTER SYSTEM SET auto_split_tablet_size = '40G' TENANT = 'your_tenant';
同时需要开启自动分区开关:
sql
ALTER SYSTEM SET enable_auto_split = true TENANT = 'your_tenant';
这里有一个工程上的判断值得注意:阈值不宜设置得过小。阈值过小意味着分区数量随数据量线性增长,元数据量膨胀、分区裁剪效率下降、合并和调度开销上升,这些问题会在表数量多、数据量大的集群中累积成系统性的负担。
2.3 已有表的改造
自动分区不只适用于新建表。对于已经存在的表,可以通过ALTER TABLE修改其自动分区属性,将一张手动分区的表转化为自动分区表,或者在自动分区表和普通分区表之间切换。这意味着迁移路径是平滑的:不需要为了使用自动分区而重建表,可以在业务运行中逐步调整分区策略。
第三章 从安装到触发第一次分裂
3.1 桌面版的安装门槛
OceanBase桌面版依赖WSL 2,需要Windows 10 1903及以上版本或Windows 11。安装过程本身相当简洁:启用WSL功能和虚拟机平台,安装WSL 2内核,设置默认版本为2,然后运行OceanBase桌面版的安装程序。官方文档给出的最低资源要求是1 vCPU、2GB内存和5GB磁盘,但实际体验中,6GB空闲内存是一个更现实的起点。如果希望运行得流畅一些,8核16线程、32GB内存和50GB以上剩余空间的配置会舒适得多。
桌面版目前仅支持MySQL兼容模式。对于自动分区的体验来说,这不是一个障碍,因为自动分区的核心语法和行为在MySQL模式下是可用的。安装完成后,桌面版提供一个图形化管理界面,点击启动后等待数秒,一个完整的OceanBase实例就在本机跑起来了。
3.2 建表与观察
在桌面版的SQL窗口中创建一个自动分区表,将SIZE设置为一个较小的值以便在测试数据量下触发分裂。例如,将SIZE设为100MB,然后通过批量插入或生成测试数据的方式让表的数据量超过这个阈值。
分裂的触发不是瞬时的。系统需要在后台调度分裂任务,分裂的时机与合并周期和资源状况有关。在桌面版的小资源环境中,可能需要等待一段时间或者手动触发一次合并,才能观察到分区数量的变化。
观察分区状态可以通过查询系统视图完成。关注的重点不是分区数量的绝对值,而是分裂前后的变化:表从一个分区变成多个分区,每个分区的数据量回落到阈值以下,查询的执行计划中出现了分区裁剪的迹象。这个过程本身比任何文档描述都更能说明自动分区的实际行为。
3.3 体验中的几个观察
第一个观察是分裂的透明性。在插入数据的过程中,业务侧的写入没有因为分裂而中断,查询也没有出现明显的延迟尖刺。这与自动分区设计目标中的Online特性是一致的:分裂不阻塞普通DML和查询。
第二个观察是阈值的决定性作用。当阈值设置得较小时,分裂发生得更频繁,分区数量增长得更快;当阈值设置得较大时,分裂的间隔更长,分区数量在测试窗口内可能根本不变。这提醒使用者,自动分区不是一个"开了就完事"的开关,阈值的选择直接决定了分区策略的实际形态。
第三个观察是全局索引的行为。默认情况下,未显式声明LOCAL的索引是全局索引。在自动分区表上,全局索引是否自动分裂取决于表的自动分区状态和索引自身的分区键条件。如果只关注主表的分裂而忽略了全局索引,索引侧可能仍然存在热点,查询性能的收益会打折扣。
第四章 自动分区改变了什么
4.1 对DBA:从预测者到阈值设定者
手动分区时代,DBA的核心工作之一是预测数据分布并据此设计分区规则。这需要DBA同时理解业务的数据模型、访问模式和增长趋势,是一项高度依赖经验的工作。预测的准确性无法在事前验证,只能在运行数月甚至数年后通过问题暴露来检验。
自动分区把这个角色从预测者转变为阈值设定者。DBA不再需要回答"数据会怎么分布",只需要回答"每个分区最大允许多大"。后者的判断依据是系统资源的约束和运维的舒适区,而不是对业务未来的猜测。阈值设置得偏保守,分区数量会多一些,元数据开销会大一些;阈值设置得偏激进,单个分区会大一些,分裂的收益会晚一些出现。这个权衡比预测数据分布要直观得多。
4.2 对业务:从分区规划到自然生长
对业务方而言,自动分区消除了建表时的一个决策负担。开发团队在创建一张新表时,不需要再和DBA讨论分区键的选择、分区数量的估算、未来扩容时的分区调整方案。表以最简单的形态创建,在数据增长的过程中自然获得合适的分区数量。
这个变化在小表多的场景中尤为明显。一个集群中可能有数百张表,大部分表的数据量很小,手动为每一张表设计分区规则既无必要也不经济。自动分区让小表保持单分区状态,只有真正增长起来的大表才触发分裂,资源的分配与数据的实际体量对齐。
4.3 对系统:负载均衡从静态设计变为动态过程
OceanBase的分布式能力依赖于数据在多个节点上的打散。手动分区下,打散的效果取决于建表时的分区设计是否与数据分布匹配。自动分区下,打散成为一个持续进行的过程:随着数据增长,分裂产生的新分区被调度到不同的节点,负载均衡从一次性的设计决策变成了一个动态的、由数据驱动的持续过程。
这个变化的意义在于,它使分布式架构的红利不再依赖于使用者的分区设计水平。一个不擅长分区设计的团队,在自动分区的帮助下,也能获得大致合理的负载分布。这降低了OceanBase的使用门槛,也让DBA的精力可以更多地放在索引优化、SQL调优和容量规划这些同样重要但更难以自动化的领域。
第五章 边界与注意事项
5.1 自动分区不是万能的
自动分区的适用边界是明确的。它仅支持Range或Range Columns分区的一级分区,且表必须有主键,分区键必须是主键的前缀。List分区、Hash分区、二级分区、无主键表、堆组织表都不在自动分区的支持范围内。如果表所在的表组中包含多张表,自动分区也不生效。物化视图、全文索引、空间索引和向量索引的自动分裂同样不被支持。
这些限制意味着,自动分区覆盖的是分区场景中最常见的一类,而不是全部。对于不满足条件的表,仍然需要手动设计分区规则,或者接受不做分区的现状。
5.2 阈值设置与分区数量的平衡
阈值过小导致分区数量膨胀,是自动分区使用中最常见的陷阱。分区数量过多会带来元数据管理的开销、分区裁剪效率的下降以及合并调度复杂度的上升。在列存表场景中,建议单个分区的行数不少于一百万行,这个经验值可以作为阈值设置的一个参考锚点。
一个务实的策略是,先设定一个相对保守的较大阈值,观察一段时间的分区增长和查询性能,再根据实际情况向下调整。从大到小调整比从小到大调整更容易控制风险,因为分区数量的增长是不可逆的,而合并和收缩的代价远高于分裂。
5.3 全局索引的配套设置
如果业务在自动分区表上使用了全局索引,需要显式开启全局索引的自动分区策略:
sql
ALTER SYSTEM SET global_index_auto_split_policy = 'ALL';
未开启时,全局索引可能以单分区形态存在,成为流量热点,抵消主表分裂带来的均衡收益。全局索引的自动分区与主表的自动分区在逻辑上是联动的,但配置上需要单独确认,这是一个容易遗漏的细节。
结语
自动分区在OceanBase的功能清单里不算一个显眼的大特性。它没有引入新的数据类型,没有改变SQL语法,也没有增加新的部署形态。它做的事情很窄:在数据量超过阈值时,把一个分区拆成多个。但这个窄小的功能解决的是一个真实而普遍的问题:分区设计的预测负担。它把DBA从"数据会怎么分布"的猜测中解放出来,把业务从"建表时要分多少区"的决策中解放出来,把负载均衡从一个静态的设计目标变成了一个动态的持续过程。
桌面版的意义在于,它让这个特性的体验门槛降到了最低。不需要一套多节点集群,不需要复杂的部署流程,一台装了WSL 2的Windows机器,半小时之内就能建一张自动分区表,插一些数据,等一次分裂,亲眼看到分区从一到多的过程。对于正在评估OceanBase的团队来说,这种低成本的上手体验,比任何文档描述都更有说服力。
小功能大作用这句话在这里是贴切的。自动分区没有试图解决所有分区问题,它只是在最常见的Range分区场景中,用最少的用户输入,换来了合理的分区自动化和负载均衡。在数据库功能日益庞杂的今天,这种克制而有效的设计,本身就值得被认真对待。