现在的位置: 首页 > 综合 > 正文

有关 ORA-00604 错误的总结

2013年01月25日 ⁄ 综合 ⁄ 共 6569字 ⁄ 字号 评论关闭

 

ORA-00604 error occurred at recursive SQL level string 

CauseAn error occurred while processing a recursive SQL statement a statement applying to internal dictionary tables)。

ActionIf the situation described in the next error on the stack can be corrected, do so; otherwise contact Oracle Customer Support.

  ORA-00604: 递归某个SQL 层时出现错误

  原因:在运行一条递归SQL语句(该语句将应用于对内部表或数据字典的操作)时,发生错误。

方案:如果上述描述的错误所在栈可以被修复,则修复并继续运行;否则,请联系Oracle客服。当然,那是Oracle官方的解决办法。

我曾经记得有个高手总结了关于ORA-00604/ORA-04031问题的解决:

  修改INIT.ora

添加_db_handles_cached = 0并重新启动数据库。

  分析:ORA-00604这个信息表明,在数据库执行内部SQL语句时,发生了错误。比如,要往表中插入一行数据,但没有可扩展的空间。ORACLE于是去查寻,哪儿可以建立下一个扩展空间,它有多大小,但没有成功。一般在发生ORA-00604错误时,还伴随着其它的错误,例如:ORA-1547等。

  

首先,应当检查警告文件alertSID.log,查找有关ORA-600类的信息。

  该错误最常见的原因是数据库文件initSID.ora中的参数OPEN_CURSORS值太小。可以修改initSID.ora文件,OPEN_CURSORS的值一般为255.修改完后,宕下ORACLE,再重新启动。

  还可以设置并启动数据库的事件跟踪功能。在initSID.ora中加上一行:

event = "00604 trace name errorstack"

宕下并重新启动ORACLE,使这个事件跟踪参数起作用。这样,当再发生ORA-604错误时,有关信息就保存在TRACE文件中。

  造成ORA-00604错误的其它原因可能有:

  - initSID.ora中,参数DC_FREE_EXTENTSROW_CACHE_ENQUEUES太低。可以根据操作系统和数据库的情况,适当增加这两个参数的值,宕下并重新启动ORACLE.

  运行超出空间(伴随ORA-1547错误)。这时,要对表空间添加新文件,即增加表空间的大小。

达到了MAX_EXTENTS(伴随ORA-1556错误)。如果这样,就要修改表,允许更多的扩展。请从技术手册中查找MAX_EXTENTS的最大值。如果已经达到了最大值,必须用compress extents选项,把表卸出(export),再导入(import)数据库中。

案例一:Oracle执行递归查询的时候出错

  问题描述:我经常遇到ORA-00604 ORA-01000(开启游标数量达到最大值)错误。然而,当我检查代码的时候,所有的结果集和语句对象都在最后的块中关闭了(我使用的是JDBC)。我执行的查询是一个Oracle递归查询(以这个开始并通过这个连接)。您能告诉我是哪里出现了问题,以及在什么样的情况下会出现上述的错误吗?

  解决方案:可能是init.ora 文件中的open_cursors 参数值的设置太低了。它应该设置为200或者更高。即使是你关闭了结果集,但是你并没有在JAVA代码中关闭SQL语句,就会导致这个问题。

  如果设置为yes的话,那么确保你的活动连接池启用了(为了性能的原因),否则设置为no.

请你的数据库管理员监视数据库,并看看使用V$OPEN_CURSORS 和 V$SYSSTAT数据字典视图的条目。

案例二:Exp出错的一个案例

  问题描述:客户用的Linux系统,Redhat 企业版(RHEL 3.0)。数据库,安装的9iR2, 前一段时间升级过。现在的版本是9204.

  客户准备要做Exp导出,以前一直系统没有空间。先给给系统扩了一些空间。Linux下的LVM还算比较好用。虽然文件系统用的是ext3 ,要暂时停机。

  进行导出操作,不成功,发现系统报告错误:

EXP-00056: ORACLE error 942 encountered
ORA-00942: table or view does not exist
EXP-00000: Export terminated unsuccessfully

  很多朋友可能对这个错误都很熟悉。

  哦,对了,客户说是升级过数据库,首先猜测是不是升级有问题?毕竟在论坛上类似升级不成功的问题看过很多了。

  执行$ORACLE_HOME/rdbms/admin/catpatch.sql 脚本。

  同时要注意调大java_pool_size shared_pool_size这两个参数的大小,要不重新来就耽误时间了,不要犯低级错误

SQL>shutdown immediate;
SQL>startup migrate;
SQL>@?/rdbms/admin/catpatch.sql

  之后查看Spool 出来的日志。 发现有编译错误,重新执行了第二次。 等待……之有这个时候我才想起才抱怨CPU不够快,内存不够大 ;)

  这次Log没错误。不料想……用户连接报告错误:

ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-04045: errors during recompilation/revalidation of LBACSYS.LBAC_EVENTS
ORA-06508: PL/SQL: could not find program unit being called
ORA-06512: at line 2
ORA-06508: PL/SQL: could not find program unit being called
ORA-06512: at line 2

  发现connect / as sysdba 还是可以登陆进去的。

  看来是 LBACSYS.LBAC_EVENTS的状态有点问题。联接进去,编译一下如何? 我的如意算盘是@/rdbms/admin/utlrp.sql执行一下就没有问题了,不料根本没有用,错误依然。当时有些头晕,这系统还没有备份呢,看来有些麻烦了(心里暗地埋怨客户,一直不让备份,总说"等等再说",作为一个DBA说话总不被重视也挺悲哀的不是? ,虽然我自己偷着有个备份,不过还是上次升级时候的呢),赶紧上网Metalink查查,这里网络速度还不错 LBACSYS.LBAC_EVENTS 作为关键词,找到如下的信息:

The reason for this problem seems to be an Upgrade for Label-Security
even if it's not installed.  //Label security 没有安装,居然补丁去默认给升级?

  解决方案:

shutdown immediate;
startup migrate;
alter view lbacsys.lbac$all_table_policies compile;
alter package lbacsys.lbac_events compile body;
shutdown immediate;
startup;

  支持人员说这是个Bug.但是普通用户不可见。 不太放心,再找找,在Suse.com站点的Maillist也发现了一则类似的案例,看来还可以,心里有底了。

  按照上面的执行,重新检查,OK.

  总结一下

其实是一个很没有技术含量的Case.首先以前升级的时候至少要测试一下Export是否可以(Export已经成为升级成功的一个标志了!) 其次,准备不够充分,成了手忙脚乱。所幸不是关键系统,用户还可以容忍。Oracle 总说微软是个烂公司,其实他们才真的够栏。Bug多的不可胜数。

  案例Sql_trace进行Oracle诊断案例

  问题说明:很多时候,在我们进行数据库操作时,比如drop userdrop table等,经常会遇到这样的错误

  ORA-00604: error occurred at recursive SQL level 1 .

  这样的提示,很多时候是没有丝毫用处的。本案例就这一类问题提供一个思路及方法供大家参考。

  1. drop user出现问题

  报出以下错误后退出

  ORA-00604: error occurred at recursive SQL level 1

  ORA-00942: table or view does not exist .

  关于 recursive SQL 错误我们有必要做个简单说明。

  我们知道,当我们发出一条简单的命令以后

  Oracle数据库要在后台解析这条命令,并转换为Oracle数据库的一系列后台操作。

  这些后台操作统称为递归sql.

  比如create table这样一条简单的DDL命令,Oracle数据库在后台,实际上要把这个命令转换为对于obj$tab$col$等底层表的插入操作。Oracle所作的工作可能比我们有时候想的要复杂的多。

  2.跟踪问题

  我们知道Oracle提供sql_trace的功能

  可以用于跟踪Oracle数据库的后台递归操作。

  通过跟踪文件,我们可以找到问题的所在

  以下是格式化(tkprof)后的输出:

The following statement encountered a error during parse:
DELETE FROM SDO_GEOM_METADATA_TABLE WHERE SDO_OWNER = 'WAPCOMM'
Error encountered: ORA-00942

Oracle把错误信息首先呈现出来,我们看到ORA-00942错误是由于

SDO_GEOM_METADATA_TABLE/视图不存在所致,问题由此可以定位。

  对于这一类的错误,定位问题以后解决的方法就要依据具体问题原因而定了。

  3.问题定位

  对于本案例,通过Metalink获得以下解释:

Problem Description
The Oracle Spatial Option has been installed and you are encountering
the following errors while trying to drop a user, who has no spatial tables,
connected as SYSTEM:
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-00942: table or view does not exist
ORA-06512: at line 7
A 942 error trace shows the failing SQL statement as:
DELETE FROM SDO_GEOM_METADATA_TABLE WHERE SDO_OWNER = ''
Solution Description

(1)

Create a synonym for SDO_GEOM_METADATA_TABLE under SYSTEM which points to
MDSYS.SDO_GEOM_METADATA_TABLE.

  对于本例,为MDSYS.SDO_GEOM_METADATA_TABLE创建一个同义词即可解决,是相对简单的情况。

(2)

Now the user can be dropped connected as SYSTEM.
Related Documents
ORA-604 and ORA-942 Reported During DROP USER CASCA

4.实际处理

  MDSYS.SDO_GEOM_METADATA_TABLESpatial对象如果未使用Spatial选项,可以删除

SQL> connect / as sysdbaConnected.
SQL> select * from dba_sdo_geom_metadata order by owner;
select * from dba_sdo_geom_metadata order by owner
*
ERROR at line 1:
ORA-00942: table or view does not exist
ORA-04063: view "MDSYS.DBA_SDO_GEOM_METADATA" has errors
SQL> select object_name from dba_objects where object_name like '%SDO%';
OBJECT_NAME
ALL_SDO_GEOM_METADATA
ALL_SDO_INDEX_INFO
ALL_SDO_INDEX_METADATA
DBA_SDO_GEOM_METADATA
DBA_SDO_INDEX_INFO
DBA_SDO_INDEX_METADATA
....
DBA_SDO_GEOM_METADATA
DBA_SDO_INDEX_INFO
...
SDO_WITHIN_DISTANCE
USER_SDO_GEOM_METADATA
USER_SDO_INDEX_INFO
USER_SDO_INDEX_METADATA
88 rows selected.
SQL> drop user MDSYS cascade;
User dropped.
SQL> select owner,type_name from dba_types where type_name like 'SDO%';
no rows selected
SQL>
SQL> alter session set sql_trace=true;
Session altered.
SQL> drop user wapcomm;
User dropped.
SQL> alter session set sql_trace=false;
Session altered.
SQL> exit
Disconnected from Oracle8i Enterprise Edition Release 8.1.7.4.0 - 64bit Production
With the Partitioning option
JServer Release 8.1.7.4.0 - 64bit Production

这时用户得以顺利drop

  5.一点总结

使用sql_trace可以跟踪数据库的很多后台操作有利于我们发现问题的所在,很多时候,我们想要研究Oracle的内部活动或后台操作,也可以通过sql_trace跟踪,sql_trace/10046 Oracle提供的最为有效的诊断工具之一。

  案例:表更新时发生递归SQL2级失败错误

  问题描述:表更新的时候失败了,并且生成了一条ORA-00604 错误信息。这个错误发生在递归SQL 2级。

  解决方案:不幸的是,这个错误并不能告诉你Oracle数据库在错误发生的时候正要做什么。当你执行一条SQL语句的时候,Oracle数据库为你在幕后做很多事情。例如,考虑下面的SQL语句:

UPDATE emp SET sal = sal*1.05 WHERE empno=1001;

  这条SQL

抱歉!评论已关闭.