ORA-12036报错咋整,物化视图日志没清空刷新卡壳远程帮忙解决
- 问答
- 2026-01-14 10:37:06
- 1
客户那边一大早打电话过来,说有个关键的数据看板不更新了,卡在昨天的数据,一查数据库日志,满屏的ORA-12036错误,这错误我熟啊,十有八九是物化视图日志(我们习惯叫MV Log)这个“小本本”记满了,没清空,导致后续的快速刷新(Fast Refresh)全都卡壳了,这事儿就像收银员的小账本,每一笔卖出去的商品都记上,方便晚上对账,但要是只记不擦,本子写满了,新的交易就没法记,账自然就对不上了。
第一步:先确认问题,别急着动手
远程连上客户的数据库,我可不敢上来就瞎操作,得先看看是不是真的因为这个,打开SQL Plus,连着跑了几个命令:
第一,查物化视图本身的状态,看它最后一次刷新是啥时候,用的什么方式刷新:
SELECT mview_name, last_refresh_type, last_refresh_date FROM user_mviews WHERE mview_name = '你的物化视图名字';
(来源:根据Oracle官方文档对USER_MVIEWS视图的常用查询方法)
果然,LAST_REFRESH_TYPE显示是FAST,但LAST_REFRESH_DATE已经是昨天的时间了,说明从那时起快速刷新就失败了。
第二,直接去查物化视图日志里是不是堵着一大堆没处理的数据,物化视图日志其实是一张名字像MLOG$_基表名的表:
SELECT COUNT(*) FROM MLOG$_你的基表名字;
(来源:Oracle物化视图日志的内部实现机制,其以MLOG$_为前缀的表结构)

这一查,数字大得吓人,好几万条记录堆在那里,正常情况下降,快速刷新成功后,这些记录应该被清掉的,现在堆这么多,明显是“交通堵塞”了。
第三,再仔细看看具体是哪些操作堵住了(是INSERT了,UPDATE了,还是DELETE了):
SELECT DISTINCT dmltype FROM MLOG$_你的基表名字;
(来源:同上,MLOG$_表结构中的DMLTYPE字段用于标识操作类型)
看到有'I','U','D'各种类型,说明增删改的操作都有积压,到这步,基本就确诊了,就是物化视图日志没被清理导致的ORA-12036。
第二步:分析堵死的根本原因
问题确认了,但得想想为啥会堵死?不能光治标不治本,常见的原因有几个:

-
有个漫长的事务没提交:这是最可疑的,某个程序或者某个人,对基表开启了一个事务,做了操作,但一直没COMMIT也没ROLLBACK,物化视图日志为了保证数据一致性,在这个古老的事务结束前,它不敢清理掉这个事务开始之后产生的日志记录,怕万一事务回滚需要用到,这就好比那个收银员,有个顾客选了商品一直在纠结付不付钱,收银员就不能把他选商品的记录划掉,导致后面的记录也没法正常清理。 检查方法:
SELECT * FROM V$TRANSACTION;看看有没有挂起时间特别长的事务。(来源:Oracle动态性能视图V$TRANSACTION用于监控当前活动事务) -
物化视图本身刷新失败了:可能之前有一次快速刷新因为其他原因(比如网络闪断、基表结构改了)失败了,但错误没被注意到,导致日志清理工作中断,后续的刷新也跟着连锁失败。
-
有多个物化视图共用同一个日志:如果基表上建了多个物化视图都做快速刷新,其中一个刷新失败或停滞,也会影响其他物化视图的日志清理。
第三步:动手解决,一步步来
根据原因,解决办法通常是组合拳:

-
尝试强制进行完全刷新(Complete Refresh):这是最直接粗暴但也最有效的“重启大法”,完全刷新不依赖日志,而是重新全量计算数据,它会在刷新完成后顺带把物化视图日志清空。
EXEC DBMS_MVIEW.REFRESH('你的物化视图名字', 'C'); -- 'C'代表Complete(来源:Oracle内置包DBMS_MVIEW的REFRESH过程) 注意:如果物化视图很大,全量刷新会非常耗时耗资源,可能会影响数据库性能,一定要在业务低峰期操作,跟客户说明白这个风险。 -
如果完全刷新不行或者太慢,先清理挂起的事务:如果发现
V$TRANSACTION里有“元凶”,最理想的方式是找到对应的会话,通知用户提交或回滚,如果情况紧急且确定该事务可以中断,可能需要DBA强制杀掉会话(KILL SESSION)。这是个危险操作,务必谨慎。 -
万不得已,手动清理物化视图日志:如果上述方法都无效,还有一个“核弹”选项——手动删除日志内容。这绝对是下下策,因为如果操作不当,会导致数据不一致。 可以先尝试最小化删除:
DELETE FROM MLOG$_你的基表名字 WHERE ... ;但很难精准定位哪些是真正不需要的。 更彻底的方法是:TRUNCATE TABLE MLOG$_你的基表名字;(来源:对Oracle表进行截断操作的SQL命令) 重要警告:执行TRUNCATE后,所有基于此基表的物化视图必须进行一次完全刷新,否则快速刷新将永远失败,操作前必须得到客户授权并确保后果可控。
第四步:解决后的事后诸葛亮
问题处理完,不能就这么算了,得给客户提个醒,避免以后再掉同一个坑里:
- 加强监控:建议他们写个监控脚本,定期检查
MLOG$_表的记录数,超过阈值就报警。 - 审查代码:检查应用程序中是否有地方开启了事务忘了提交。
- 规范操作:提醒开发人员,修改基表结构(如增删改列)前,必须先处理掉相关的物化视图和日志。
把整个排查过程、解决方法、根本原因和建议,清清楚楚地记录下来,发给客户,这样他们以后遇到类似问题,心里也能有个底,远程帮忙解决,不只是为了当下灭火,更重要的是帮他们提升自己预防火灾的能力。
本文由酒紫萱于2026-01-14发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/80502.html
