当前位置:首页 > 问答 > 正文

树叶云带你简单聊聊OceanBase里怎么用ALTER SEQUENCE调整序列,实操步骤和注意点分享

主要参考了OceanBase官方文档中关于序列的章节以及相关技术社区的实践分享)

树叶云带你简单聊聊OceanBase里怎么用ALTER SEQUENCE调整序列

想象一下,你在OceanBase数据库里创建了一个序列,就像拿到了一个自动发号的机器,可以源源不断地生成唯一的订单号、用户ID什么的,但用着用着,你可能会发现:“哎呀,这个号从1开始太小儿科了,能不能从10000开始显得我们业务规模大?”或者“每次涨1太慢了,能不能一次涨10?”再或者“这个号有上限吗?会不会有一天号用完了?”。

这时候,你就需要请出ALTER SEQUENCE这个神奇的命令了,它就像是这个发号机器的调节按钮,让你在不重启服务、不影响现有数据的情况下,动态调整序列的“工作模式”,下面我们就来实际操练一下。

先来个热身:创建一个用于练习的序列

在调整之前,我们得先有个序列,打开你的OceanBase客户端(比如OBClient、ODC或者命令行),执行下面这个简单的命令:

CREATE SEQUENCE seq_demo START WITH 1 INCREMENT BY 1 CACHE 100;

(来源:OceanBase CREATE SEQUENCE语法说明)

这条命令创建了一个名为seq_demo的序列,它从1开始,每次增加1,并且为了性能考虑,会一次性在内存中缓存100个值,我们可以用NEXTVAL来获取下一个值了:SELECT seq_demo.NEXTVAL FROM DUAL;,它会返回1。

动手实操:用ALTER SEQUENCE调整序列

树叶云带你简单聊聊OceanBase里怎么用ALTER SEQUENCE调整序列,实操步骤和注意点分享

我们开始使用ALTER SEQUENCE来修改它,这个命令的基本格式是:ALTER SEQUENCE [序列名] [要改的参数]

  1. 修改序列的起始值(START WITH)?—— 注意,这个不行! 你可能第一个想到的是改起始值,但很遗憾,OceanBase的ALTER SEQUENCE不允许直接修改START WITH参数。(来源:官方文档明确说明START WITH不能在创建后更改)这是序列的一个“出生属性”,一旦设定就无法通过ALTER改变,如果你真的需要一个新的起始点,常见的做法是创建一个新的序列。

  2. 修改增量步长(INCREMENT BY) 我们希望序列号不是一个个增加,而是以10为单位增加,这样看起来更整齐或者满足某种业务间隔需求。

    ALTER SEQUENCE seq_demo INCREMENT BY 10;

    执行完后,你再调用SELECT seq_demo.NEXTVAL FROM DUAL;,会发现下一个值比上一个值大了10,这个修改是立即生效的。

  3. 修改最小值(MINVALUE)和最大值(MAXVALUE) 默认情况下,序列可能没有最小值限制(或为1),最大值可能是一个很大的数,但你可以为它设定边界,我们想限制这个序列在100到999之间循环。

    树叶云带你简单聊聊OceanBase里怎么用ALTER SEQUENCE调整序列,实操步骤和注意点分享

    ALTER SEQUENCE seq_demo MINVALUE 100 MAXVALUE 999 CYCLE;

    这里我们同时做了两件事:

    • 设置了最小值100和最大值999。
    • 加上了CYCLE关键字,表示当序列达到999后,下一个值会回到100重新开始,如果不希望循环,而是到达最大值后报错,可以使用NOCYCLE(默认行为)。
  4. 修改缓存大小(CACHE) 缓存是为了提高性能,一次性预取多个序列值放到内存里,如果应用获取序列非常频繁,增大缓存可以减少数据库的I/O压力,但要注意,如果数据库实例重启,缓存中未使用的序列值会丢失,导致序列号出现“断层”(比如1,2,3, 然后直接跳到105,106...),这是正常现象。

    ALTER SEQUENCE seq_demo CACHE 200;

    这把缓存大小从100增加到了200。

  5. 修改其他属性

    • 重启序列(RESTART):这不是指回到最初的起点,而是将序列的NEXTVAL设置为当前值。(来源:社区实践分享)这个功能在某些OB版本中可能通过特定方式实现,但标准的ALTER SEQUENCE ... RESTART语法可能不完全等同于其他数据库,更常见的重置序列值的方法是先删除再重建,或者通过复杂查询计算出一个新起点后间接设置,操作前务必在测试环境验证。
    • 是否有序(ORDER/NOORDER):在分布式数据库 like OceanBase中,ORDER保证生成的序列号是严格顺序的,但可能影响性能;NOORDER则优先保证性能,生成的号在全局上可能是近似有序的,你可以根据业务对顺序性的要求来更改。
    ALTER SEQUENCE seq_demo ORDER; -- 改为保证严格有序

非常重要的注意点分享(避坑指南)

  1. 权限问题:你不是随便谁都能改序列的,你需要拥有这个序列的ALTER权限或者是该序列所在Schema的拥有者。(来源:OceanBase权限管理体系)
  2. 起始值(START WITH)不可更改:这是最容易踩的坑,再强调一次,规划时要慎重。
  3. 缓存与序列号间隙:只要使用了CACHE,就一定会因为数据库重启、事务回滚等原因产生序列号间隙(不连续),这是为了性能做出的权衡,是正常现象,如果你的业务严格要求连续(如发票号码,法律上有连续要求),可能需要考虑不使用缓存(NOCACHE)或其他方案,但要承受性能下降的代价。
  4. 修改的影响是立即且永久的ALTER SEQUENCE命令一旦成功,新的设置会立即对所有后续获取序列值的会话生效,修改前一定要评估对现有业务逻辑的影响,你把增量从1改成10,那么下一个插入数据的业务逻辑是否还能正常工作?
  5. 分布式环境下的考虑:OceanBase是分布式数据库,序列本身可以保证全局唯一,但像ORDER这样的属性在分布式节点间协调会有开销,在追求极高并发性能的场景下,如果业务可以接受不严格的顺序,使用NOORDER会是更好的选择。
  6. 测试!测试!测试!:在任何对生产环境的序列进行修改之前,务必在测试环境进行完整的验证,模拟真实业务场景,确认修改后的序列行为符合预期,不会导致程序错误或数据问题。

ALTER SEQUENCE是一个很有用的工具,它赋予了我们在序列生命周期内灵活调整的能力,但“能力越大,责任越大”,使用它的时候,清楚每个参数的含义和潜在影响,做好充分测试,才能让它真正为你的业务服务,而不是添乱,希望这些实操步骤和注意点能帮到你!