今天同事手一抖,误删除了一套测试环境中的所有sequence序列对象。序列不像表这种对象,drop删除可以从回收站中找回来,当然一般认为序列并不是那么重要,只要记得名称以及一些非默认参数,可以选择重建。唯一可能有问题的就是,一般序列常用于主键字段,如果之前的序列已经被用了,他的last_number可能就不是初始值了,换句话说,如果此时只是简单地重建,很有可能使用过程中,会出现seq.nextval的值之前已经用了主键,此时会报ORA-00001约束冲突的错误。


我觉得针对这个问题,有两种解决方法。

1. create sequence的时候设置minvalue为一个比较大的值,尽量可以超过之前使用的值。但这种方法掺杂蒙的成分,且不一定准确。

2. 是否可以找回之前删除的序列?


对于问题2,答案是可能找回,可能找不回。


1. 可能找回的实验

之所以可以找回,原理就是用闪回,准确说是闪回查询的方法,利用的就是UNDO表空间,如下可以检索dba_seqences视图中sysdate - 60/1440,即1小时之前的数据镜像,

误删除序列sequence,是否可以找回?_字段


之前我们说了,之所以不是直接重建,是因为我要知道删除之前,序列last_number用到什么了,因此拼接create sequence的时候可以将minvalue参数值设为last_number的实际值。同时可以指定序列属主,避免扰乱,

误删除序列sequence,是否可以找回?_字段_02


使用minus将当前和历史镜像相减,是另一种方法,

误删除序列sequence,是否可以找回?_表空间_03


sys.seq$亦可以检索序列,但需要使用OBJ#字段和dba_objects的OBJECT_ID字段关联才可以知道对应的序列名称,

误删除序列sequence,是否可以找回?_闪回_04


无论用什么方法,得到SQL语句,就可以直接用来重建序列了。


2. 不可能找回的实验

这问题其实和闪回查询的原理有关,因为闪回查询使用的是UNDO表空间,因此回滚段是否包含指定删除时间的镜像,就成为了是否可以找回的关键,如果当前需要找回的数据已经从UNDO删除,则可能报错ORA-01555,说明已经从UNDO找不着前镜像了,因此无法执行SQL,

误删除序列sequence,是否可以找回?_字段_05


总结:

1. 使用闪回查询,可能找回删除的序列定义,进而可以知道last_number值,将其设为minvalue,就不会影响使用,相当于了断点续传的作用。

2. 若闪回查询使用的UNDO记录已被删除,此时查询报错ORA-01555,这种方法就不支持找回sequence了。



如果您觉得此篇文章对您有帮助,欢迎关注微信公众号:bisal的个人杂货铺,您的支持是对我最大的鼓励!共同学习,共同进步:)