近期,遇到ORACLE数据库在进行DROP TABLE时,无法删除,报错ORA-00604: error occurred at recursive SQL level 1,ORA-20001......的问题。
对于这种明显超出常理的问题,也无对应的后台日志,很难从报错入手排除问题。
此时的一个典型思路,是对SQL操作进行TRACE跟踪,如10046TRACE或者ERRORSTACK跟踪,来获取深层的TRACE日志,进行分析,通常可以发现问题的根因。
本次问题就是使用10046TRACE跟踪分析,或者DROP TABLE时数据库的底层SQL调用,最终发现是有1个触发器影响不让删除。
分析如下:
1、删除报错
SQL> create table KLB_PEQS1.test20210303 as select * from dba_users;
Table created.
SQL> drop table KLB_PEQS1.test20210303 ;
Table dropped.
SQL> show user
USER is "KLB_PEQS1"
SQL> create table test20210303 as select * from dba_users;
Table created.
SQL> drop table test20210303 ;
drop table test20210303
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: KLB_PEQS1.TEST20210303 ?????drop??!
ORA-06512: at line 7
SQL> select * from dba_role_privs where grantee='KLB_PEQS1';
GRANTEE GRANTED_ROLE ADM DEF
KLB_PEQS1 RESOURCE NO YES
KLB_PEQS1 DBA NO YES
KLB_PEQS1 CONNECT NO YES
SQL>
SQL> select * from dba_role_privs where grantee='KLB_PEQS1';
GRANTEE GRANTED_ROLE ADM DEF
KLB_PEQS1 RESOURCE NO YES
KLB_PEQS1 DBA NO YES
KLB_PEQS1 CONNECT NO YES
SQL> drop table test20210303 ;
drop table test20210303
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: KLB_PEQS1.TEST20210303 ?????drop??!
ORA-06512: at line 7
2、TRACE分析
SQL> select sid from v$mystat where rownum=1;
SID
786
SQL>
SQL>
SQL> drop table test20210303 ;
drop table test20210303
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: KLB_PEQS1.TEST20210303 ?????drop??!
ORA-06512: at line 7
SQL> select b.spid,a.sid,a.username,a.program,a.machine,BLOCKING_SESSION
2 from vsession a,vprocess b
3 where a.paddr=b.addr and a.sid=786;
SPID SID USERNAME
PROGRAM
MACHINE
BLOCKING_SESSION
24317 786 KLB_PEQS1
sqlplus@nf-dboracle (TNS V1-V3)
nf-dboracle
SQL>
SQL>
SQL>
SQL> oradebug setospid 24317
Oracle pid: 92, Unix process pid: 24317, image: oracle@nf-dboracle (TNS V1-V3)
SQL> oradebug event 10046 trace name context forever,level 12;
Statement processed.
SQL> oradebug tracefile_name
/u01/app/oracle/diag/rdbms/orclpri/orcl/trace/orcl_ora_24317.trc
SQL> oradebug event 10046 trace name context off;
Statement processed.
3、分析TRACE文件
TKPROF: Release 11.2.0.3.0 - Development on Wed Mar 3 11:46:43 2021
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
Trace file: /u01/app/oracle/diag/rdbms/orclpri/orcl/trace/orcl_ora_24317.trc
Sort options: default
********************************************************************************
count = number of times OCI procedure was executed
cpu = cpu time in seconds executing
elapsed = elapsed time in seconds executing
disk = number of physical reads of buffers from disk
query = number of buffers gotten for consistent read
current = number of buffers gotten in current mode (usually for update)
rows = number of rows processed by the fetch or execute call
********************************************************************************
SQL ID: asrh3b8ngw9zg Plan Hash: 0
DECLARE
l_errmsg VARCHAR2(100) := '不允许进行drop操作!';
BEGIN
IF ora_login_user NOT IN ('SYS','SYSTEM','DATA_MONITOR') THEN
raise_application_error(-20001, ora_dict_obj_owner||'.'||ora_dict_obj_name||' '||l_errmsg);
END IF;
END;
call count cpu elapsed disk query current rows
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 0 0.00 0.00 0 0 0 0
total 2 0.00 0.00 0 0 0 0
Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 5 (recursive depth: 1)