不能。kill session仅标记为killed,实际进程仍持资源并消耗回滚段,需等待pmon清理或手动immediate中断后回滚,耗时取决于undo量。
物化视图刷新卡住时,kill session 能立刻终止吗?
不能。直接执行 alter system kill session 'sid,serial#' 只会标记会话为 killed,实际进程仍持有资源、继续消耗回滚段,直到它自己完成当前事务或被 pmon 清理——这个过程可能长达几十分钟,尤其在大表刷新场景下。
常见错误现象:V$SESSION.STATUS 显示 KILLED,但 V$TRANSACTION.USED_UBLK 持续增长,V$ROLLSTAT.CURSIZ 不降反升;同时 DBA_MVIEWS.LAST_REFRESH_DATE 无更新,刷新任务“既没成功也没失败”。
- 必须先确认是否真的在刷新:查
V$SESSION的SQL_ID,再关联V$SQL.SQL_TEXT,看是否含REFRESH MATERIALIZED VIEW或大量INSERT INTO ... SELECT - 不要只依赖
STATUS = 'KILLED'判断已终止;要同步监控V$TRANSACTION和V$ROLLSTAT - 如果会话已持锁阻塞其他 DML,且无法等待,才考虑下一步的强制中断
ALTER SYSTEM KILL SESSION ... IMMEDIATE 的真实效果
加 IMMEDIATE 后,Oracle 会跳过正常清理流程,立即中断服务器进程(SPID),并触发回滚段上的前镜像(UNDO)回滚。但这不等于“秒退”——回滚速度取决于已修改的数据量和 UNDO 块数,不是指令发出就结束。
使用场景:当刷新已写入大量数据(比如千万行 INSERT)、且你明确接受回滚耗时(通常 1:3~1:5 的写入/回滚时间比),才用此命令。
- 执行前务必查
V$TRANSACTION.USED_UBLK:若 > 100000,预估回滚可能超 10 分钟 - 确保
UNDO_RETENTION足够长(至少大于预计回滚时间),否则可能报ORA-01555: snapshot too old - 执行后立刻查
V$SESSION,STATUS应变为INACTIVE;若仍为KILLED,说明 PMON 尚未介入,需耐心等或检查 alert 日志
回滚期间能否删物化视图或改基表?
不能。只要回滚还在进行,物化视图对应的 MV log 表(如 MLOG$_TBL_NAME)仍被锁定,且基表上的 DML 触发器处于活跃状态。此时删 MV 或 truncate 基表会直接报错阻塞。
典型错误信息:ORA-12008: error in materialized view refresh path 或 ORA-00054: resource busy and acquire with NOWAIT specified。
- 回滚完成前,
DBA_MVIEW_LOGS.LOG_TABLE对应的表不可 DDL,也不建议对其做 DELETE/TRUNCATE - 基表上新 DML 会被挂起等待,表现为
enq: TX - row lock contention,影响业务 - 如果急需释放空间,可考虑临时禁用 MV log:
ALTER MATERIALIZED VIEW LOG ON table_name DISABLE PRIMARY KEY(仅限测试环境验证过影响)
如何避免下次刷新又卡死?
根本不在“杀会话”,而在控制刷新行为本身。默认的 DBMS_MVIEW.REFRESH 使用 ATOMIC_REFRESH => TRUE,即全程在单个事务里做,一出错全回滚,也容易撑爆 UNDO。
推荐改用分批 + 非原子模式:
- 用
DBMS_MVIEW.REFRESH的atomic_refresh => FALSE参数,让刷新拆成多个小事务,失败只回滚当前批次 - 对大表,显式指定
method => 'C'(快速刷新)而非'F'(完全刷新),前提是 MV log 存在且未失效 - 刷新前检查
DBA_MVIEWS.STALENESS:若为UNUSABLE,先ALTER MATERIALIZED VIEW mv_name COMPILE,否则刷新必然失败
最常被忽略的一点:物化视图刷新任务若通过 DBMS_JOB 或 DBMS_SCHEDULER 提交,其会话的 UNDO_TABLESPACE 是继承自 job 创建者用户的默认表空间,而不是当前连接用户设置的。这意味着即使你连的是有大 UNDO 的用户,job 刷起来照样可能因 UNDO 不足而卡死。










