ORA-04098錯誤解決方法
2024-07-21 02:09:44
供稿:網友
ora-04098錯誤解決方法
數據庫版本:8.1.5
平臺:solaris 5.7
背景:
用戶建立了一個trigger:
create or replace trigger ddl_deny
before create or alter or drop on database
declare
begin
insert into ddl_logs values(ora_dict_obj_owner,ora_dict_obj_name,sysdate);
exception
when no_data_found then
null;
end;
目的大概就是記錄下所有的ddl操作,但trigger建立有錯誤,發現:
11:30:08 [email protected]>alter trigger ddl_deny disable;
alter trigger ddl_deny disable
*
error 位于第 1 行:
ora-04098: 觸發器 'ddl_deny' 無效且未通過重新驗證
11:31:45 [email protected]>drop trigger ddl_deny;
drop trigger ddl_deny
*
error 位于第 1 行:
ora-04098: 觸發器 'ddl_deny' 無效且未通過重新驗證
此時觸發器不能編譯過去,也不能刪除了,因為觸發器本身里面定義了ddl操作的觸發,產生ora-04098: 觸發器 'ddl_deny' 無效且未通過重新驗證。
解決方法:
1、首先查看用戶的權限是否正確:
select owner, object_name, object_type, status from dba_objects where object_name = '<trigger_name>';
12:42:38 [email protected]>select owner, object_name, object_type, status from dba_o
bjects where object_name='ddl_deny';
owner object_name object_type status
------------------------------------ --------------
system ddl_deny trigger invalid
發現用戶權限沒有問題。
2、接著設置診斷事件alter session set events='4098 trace name errorstack level 3';,查看trace文件的內容如下:
dump file /db1/app/oracle/admin/ora250/udump/ora250_ora_6834.trc
oracle8i enterprise edition release 8.1.5.0.0 - production
with the partitioning and java options
pl/sql release 8.1.5.0.0 - production
oracle_home = /db1/app/oracle/product/8.1.5
system name: sunos
node name: db250
release: 5.7
version: generic_106541-08
machine: sun4u
instance name: ora250
redo thread mounted by this instance: 1
oracle process number: 17
unix process pid: 6834, image: [email protected] (tns v1-v3)
*** session id30.829) 2004.11.17.20.53.38.000
*** 2004.11.17.20.53.38.000
ksedmp: internal or fatal error
ora-04098: 觸發器'ddl_deny' 無效且未通過重新驗證
current sql statement for this session:
alter trigger ddl_deny disable
----- call stack trace -----
calling call entry argument values in hex
location type point (? means dubious value)
-------------------- -------- -------------------- ----------------------------
ksedmp()+160 call ksedst()+0 508 ? 1 ? ffbeb31c ?
ffbeadc0 ? ffbeada4 ? 0 ?
ksddoa()+248 ptr_call 00000000 3 ? 0 ? 0 ? 16594fc ?
c0000025 ? 0 ?
ksdpcg()+212 call ksddoa()+0 16eb0ac ? 16e4c24 ? 3 ?
24939c ? 16eb0ac ? 16eb090 ?
ksdpec()+236 call ksdpcg()+0 1002 ? ffbeb8e4 ? 16e4c24 ?
0 ? 0 ? 0 ?
ksfpec()+136 call ksdpec()+0 1002 ? 165a800 ? 165a800 ?
7f3 ? 1659995 ? 16594fc ?
kgesev()+100 ptr_call 00000000 1659494 ? 1002 ? 262f80 ?
1002 ? 1 ? 0 ?
ksesec1()+48 call kgesev()+0 1659494 ? 16e8ca4 ? 1002 ?
1 ? ffbeba60 ? 1 ?
kkttrex()+2112 call ksesec1()+0 1002 ? 1 ? 8 ? 8e859d26 ? 2 ?
2 ?
kktexeevt()+616 call kkttrex()+0 8e996a20 ? 8e973b48 ?
ffbebae4 ? 1659000 ?
8e859d6c ? 165e800 ?.....
發現是內部嚴重錯誤,其他看不出太多錯誤信息,于是想到采用隱含參數_system_trigger_enabled=false,在數據庫啟動的時候讓所有觸發器不起作用,然后刪除。數據庫8.1.5的提示沒這個參數,于是查詢了一下:
14:28:32 [email protected]>select ksppinm from x$ksppi where substr(ksppinm,1,1)='_'
and ksppinm like '%tri%' order by ksppinm;
ksppinm
-------------------------------------------------------------------------------
_cleanup_rollback_entries
_distributed_lock_timeout
_distributed_recovery_connection_hold_time
_number_cached_attributes
_system_trig_enabled
發現8.1.5版本的參數是_system_trig_enabled,于是讓用戶在初始化參數文件中設置此參數為false,然后重啟數據庫,刪除trigger,刪除成功。
至此問題解決。