场景:
触发刷新的场景有:
1.刚开始对数据库进行的初始化刷新
2.一个commit
3.根据一个预定计划的job来对物化视图进行刷新
问题的场景,是通过一个预定的计划来对物化视图做刷新操作。
-
CREATE MATERIALIZED VIEW TESTMV
-
NOLOGGING
-
BUILD DEFERRED
-
REFRESH COMPLETE ON DEMAND
-
NEXT trunc(sysdate + 1,'dd') + (1/24)
-
AS
-
SELECT * FROM EMP;
提示:NEXT的语法会制定物化视图在凌晨一点钟执行刷新操作。
如果job失败的话,job子系统会再次执行它。
这将会导致一个场景,系统会变得很忙,总是想完成这个刷新操作,特别是物化视图比上述所说的还要复杂的时候、
解决方案:
以下的sql语句可以知道哪些job是在当前被计划中的:
-
COLUMN JOB HEADING 'Job ID' FORMAT 999999
-
COLUMN PRIV_USER HEADING 'Privilege|Schema' FORMAT A10
-
COLUMN RNAME HEADING 'Refresh|Group|Name' FORMAT A10
-
COLUMN ROWNER HEADING 'Refresh|Group|Owner' FORMAT A10
-
COLUMN BROKEN HEADING 'Broken?' FORMAT A7
-
-
SELECT J.JOB,
-
J.PRIV_USER,
-
R.ROWNER,
-
R.RNAME,
-
J.BROKEN
-
FROM DBA_REFRESH R, DBA_JOBS J
-
WHERE R.JOB = J.JOB
-
ORDER BY 1;
你的输出会看到跟如下相似的结果:
-
Refresh Refresh
-
Privilege Group Group
-
Job ID Schema Owner Name Broken?
-
------- ---------- ------------ ---------- -------
-
26 SCOTT SCOTT TESTMV N
上述会显示你要的Job id号和对应的物化视图名称。Broken这一列表示job是否考虑继续执行,一个已经broken的job是不会继续执行的。
再根据job id号,看看下面又发生了什么
-
col last_date format a10
-
col last_sec format a10
-
col next_sec format a10
-
col interval format a20
-
col what format a30
-
col what broken a10
-
-
select job,last_date, last_sec,
-
total_time,next_date,next_sec,what,interval,broken
-
from DBA_JOBS
-
where job=n;
最后,通过下面的语句,看看哪个job是当前正在运行的
-
SELECT * FROM V$MVREFRESH
你会看到相似的输出:
-
Session Serial Materialized
-
Identifier Number Owner View
-
---------- ------- --------------- -------------------------
-
19 233 SCOTT TESTMV
这个例子说明被scott用户所拥有的物化视图TESTMV正在被刷新中,你可以执行下面的语句取消当前回话的刷新操作。
-
ALTER SYSTEM KILL SESSION 19,233;
下面是干货,会话failed之后,job会重新的re-schedule的刷新操作。
为了防止这个情况的发生,你需要在取消操作之前先mark一下broken,让job不再re-scheuled。
通过以下的操作,操作的用户是MV的拥有者,而不是sysdba
-
sqlplus scott/tiger(这个用户是你实际运行的用户)
-
SQL> BEGIN
-
DBMS_JOB.BROKEN ( n, true);
-
commit;
-
END;
-
/
注意:n对应的是你的job id号。
现在可以重新测试一下job是否为broken了:
-
Refresh Refresh
-
Privilege Group Group
-
Job ID Schema Owner Name Broken?
-
------- ---------- ------------ ---------- -------
-
26 SCOTT SCOTT TESTMV Y
你可以执行以下操作删除当前的进程:
-
ALTER SYSTEM KILL SESSION 19,233;
这个刷新操作再也不会发生,除非你又重新标记job为"not broken",想如下所做:
-
sqlplus scott/tiger
-
SQL> BEGIN
-
DBMS_JOB.BROKEN ( n, false);
-
commit;
-
END;
-
/
删除物化视图本身也会移走job队列中的job。
阅读(7113) | 评论(0) | 转发(0) |