今天试图删除重建一个定时刷新的物化视图时直接卡死,过阵时间会报"Oracle ORA-04021 等待锁定对象时发生超时"的错误.
解决方法大致有两种
1被job锁死 (大部分百度答案)
查询
select * from dba_jobs_running;
根据上步查出的sid寻找session
select s.sid,s.serial#,p.spid from v$session s left join v$process p on s.paddr=p.addr where sid=114;
杀死job进程
alter system kill session '253,14396';
但是我遇见的不是这种情况.并没有执行中的job进程锁死物化视图.
2.删除相关记录时卡住(按照官方说法应该是12.2以后的oracle会出现此问题)
查询被锁资源
select l.oracle_username,o.owner,o.object_name,o.object_type,s.sid,s.serial#,p.spid
from v$locked_object l, dba_objects o, v$session s, v$process p
where l.object_id = o.object_id
and l.session_id = s.sid
and s.paddr = p.addr order by o.object_id;
查询所有锁发现mvref_stats.mvref$ _run_stats,mvref$ _change_stats,mvref$_stmt_stats等几个表被锁定.
看表名开头mvref应该是和物化视图刷新有关的.
去oracle官网搜了下
“启用10046跟踪’drop mview’命令执行显示如下查询的等待较多,该查询实际上对此表执行了删除操作 - “SYS.MVREF $
_CHANGE_STATS” DELETE FROM SYS.MVREF $ _CHANGE_STATS WHERE REFRESH_ID =:B2 AND MV_OBJ#=:B1; 这是因为,在11g版本及以前,并没有对MVIEW使用情况的跟踪。但是,从12.2开始,实现了对MVIEW操作使用情况的跟踪。”
猜测是由于删除物化视图时要先从这些表里删除记录,卡住了.
查询物化视图的obj#
select obj# from sys.obj$ where name='mvname';
查下在卡住的表里有多少数据
select count(1) from sys.mvref$_change_stats where mv_obj#='110783';
好几百万条数据,怪不得会卡住.试下手动删除
delete from sys.mvref$_stats where mv_obj#='110783' ;
delete from sys.mvref$_run_stats where mviews='mvname' ;
delete from sys.mvref$_change_stats where mv_obj#='110783' ;
delete from sys.mvref$_stmt_stats where mv_obj#='110783' ;
继续删除物化视图
DROP MATERIALIZED VIEW mvname;
成功!