天天看点

关于sequence问题的紧急处理

今天早上收到邮件,说有一个很紧急的问题,是关于sequence的。

错误日志里面还有ORA的错误

-----

        ... 7 more

Caused

by: java.sql.SQLException: ORA-08004: sequence TRX_1SQ.NEXTVAL exceeds

MAXVALUE and cannot be instantiated

猛一看就是sequence的值越界了。

导致这个问题的原因主要有两个:

1)设置的maxvalue值过小了。

2)sequence的cycle模式没有启用

从库里查看sequence的状态。

SEQUENCE_NAME                   MIN_VALUE  MAX_VALUE INCREMENT_BY C O CACHE_SIZE LAST_NUMBER

------------------------------ ---------- ---------- ------------ - - ---------- -----------

   TRX_1SQ                             1  999999999            1 N N        100  1000000000

从上面的结果可以看出,sequence的cycle模式没有启用,sequence值越界了。

修复问题可以有两种思路。就是设置maxvalue,或者选择开启cycle模式。

先来看看设置maxvalue,问题就来了,需要设置多大,这个得找开发确认,而开发也不确定最大能设置多大。问题又跑到了dba这边,

关于maxvalue的值,官方文档是这么描述的。最大28位。

有了这个思路,貌似问题简单了很多。从数据库层面来说似乎行得通了,设置一个最大值即可。从业务上是不是支持更大的数值呢,这个看似需要开发来确认,但是和dba也是有一些关联的,我找到sequence相关的表,大概有5张左右的表使用了那个sequence, 查看对应的表列,可以看到有些字段是支持的,有些字段却是NUMBER(9),很明显设置maxvalue会带来更多的问题。

因为相关的几个表都是核心表,如果修改表的精度也是有潜在风险的。

这个时候就需要找开发确认,是不是应该开启cycle模式,对于现有数据是否有影响了。很快得到产品线的回馈,有同样一个问题在别的项目发生过,需要开启cycle模式。

对于dba来说,需要做的工作基本就是测试和验证了。

从生产备份库中使用dbms_metadata.get_ddl得到sequence的创建语句

SQL> CREATE SEQUENCE  "TRX_1SQ" 

MINVALUE 1 MAXVALUE 999999999 INCREMENT BY 1 START WITH 1000000000 CACHE 100

NOORDER  NOCYCLE

    /

Sequence created.

--复现问题

SQL> select trx_1sq.nextval from dual;

select csm_trx_1sq.nextval from dual

       *

ERROR at line 1:

ORA-08004: sequence CSM_TRX_1SQ.NEXTVAL exceeds MAXVALUE and

cannot be

instantiated

--修复问题

SQL> alter

sequence CSM_TRX_1SQ cycle;

Sequence altered.

 --验证问题

SQL> select csm_trx_1sq.nextval from dual;

   NEXTVAL

----------

         1

SQL> /

         2

SEQUENCE_NAME                  

MIN_VALUE  MAX_VALUE INCREMENT_BY C O CACHE_SIZE LAST_NUMBER

------------------------------ ---------- ----------

------------ - - ---------- -----------

    TRX_1SQ                            

1  999999999           

1 Y N       

100         101

当然了,如果要设置maxvalue的话。有一个细节需要注意的。

如果设置为28位,最高位是没有问题的。

SQL> alter sequence csm_trx_1sq maxvalue 9999999999999999999999999999;

SQL> select *from user_sequences where sequence_name='TRX_1SQ';

    TRX_1SQ                             1 1.0000E+28            1 Y N        100           3

但是如果你设置了30位,也是不会报错的,提示运行成功。但是查看sequence的最大长度,却还是28位。

SQL> alter sequence csm_trx_1sq maxvalue 999999999999999999999999999999;

SQL> select *from user_sequences where sequence_name='CSM_TRX_1SQ';