发现ORA-06508错误的一种新原因及解决办法

最近系统上经常捕获Ora-06508错误,发生在过程A调用过程B的时候,在网上找了下,一般都是说在过程A里drop掉某个table,再create起来,而过程B恰好调用该table就会出现这种错误。不过我们系统里没有drop table的习惯啊,都是truncate后再生成数据;而且这个过程之前都是正常运行的,最近才报出这种错误,所以只能自己找原因了。

看了下调用过程B的时间是 6:04,再将过程B所引用的对象(主要是表)生成时间查了一下,对一张备份表bak_t产生了怀疑,这张表的last_ddl_time是5:51,离调用过程B的时间最近,而过程B中实际是引用了t这张正式表。这里说下正式表t和其备份表bak_t,为了避免在界面上查询时刚好碰到t表中数据在生成而导致查询不到结果的情况,先用备份表生成当天最新的数据,再将这两张表的名称互换,因此在5:51分时就发生了两张表的“瞬间切换”。

不过到了这里我还没发现问题的所在,也没有察觉到我发现了一条重要线索,在向大叔请教之后才弄清楚了问题的原因:原来每个对象在Oracle内部都有一个object_id,当过程B执行前会先进行编译,这时是用的t这张正式表并编译通过。但是在执行之前,t被改名为bak_t,而原来的备份表则改名为了t;等到执行过程B时,虽然这时系统中有了t这张表,但是过程里却是根据object_id去查找表的,等找到的时发现表名不一样便报错了,这也是为什么查引用的对象时显示的表名是bak_t。也就是说,t和bak_t是两个对象,虽然我们经常给它们互换名字,但其内部id却一直未变。果然姜还是老的辣,有些问题虽然能够发现关键线索,但在缺乏经验时却不能将其联系起来并做出总结。

查看往期日志也能印证这种原因:查看三次报错那天的日志,都能发现切换发生在过程B编译之后(过程B所在包里最早执行的过程时间是5:30,可以看做是B的编译时间;切换则发生在5:50左右),而之前的日志则显示切换都是在编译之前就完成的,所以才会出现现在报错而以前没有错误的情况。

解决这个问题就很简单了:将过程B里引用t表的那段代码改成动态sql即可。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值