Oracle 19.29 中 ORA-12751 错误完全解析:从通用问题到 minact-scn 场景

1 引言

在日常 Oracle 数据库运维中,告警日志(alert log)里偶尔会出现如下两类信息:

复制代码
ORA-12751: cpu time or run time policy violation

以及:

复制代码
minact-scn: useg scan erroring out with error e:12751

很多 DBA 对后者感到陌生,甚至误以为数据库出现了内部 corruption。实际上,这两条信息本质上是同一问题的不同表现形式------它们都指向 MMON(Manageability Monitor)或其工作进程在执行内部操作时超出了允许的 CPU 时间或运行时间阈值

本文基于 Oracle 19.29 (19c 长期支持版本的最新补丁集),整合 Oracle 官方知识文档 KB145377KB86914,系统性地讲解:

  • ORA-12751 错误的定义与内部机制

  • minact-scn: useg scan erroring out with error e:12751 的具体含义

  • 从告警日志到 MMON 跟踪文件的完整排查流程

  • 针对不同触发场景的解决方案

  • 预防与长效监控策略

适用版本:Oracle Database 19c (19.29 及更高版本)

参考文档:KB145377, KB86914, KB148634, KB126507, 1595092.1, SRDC4224 等


2 错误定义与内在联系

2.1 ORA-12751:通用定义

ORA-12751 的错误信息为:

复制代码
ORA-12751: cpu time or run time policy violation

它表示 Oracle 数据库的某个后台进程(通常是 MMON 或其工作进程 M000, M001...)在执行内部操作时,超出了以下两个阈值之一:

  • CPU 时间限制 :操作消耗的 CPU 时间超过内部参数 _mmon_cpu_time_limit(默认 60 秒)

  • 运行时间限制 :操作的挂钟时间(wall-clock time)超过 _mmon_runtime_limit(默认 300 秒)

这是一种自我保护机制,防止某个失控的内部任务长期占用资源,导致 MMON 僵死或影响数据库可管理性。

2.2 minact-scn 告警:ORA-12751 的特殊表现形式

minact-scn: useg scan erroring out with error e:12751 是 ORA-12751 在Undo 段扫描场景下的具体表现。

什么是 minact-scn?
minact-scnMinimum Active SCN 的缩写。数据库需要维护一个"当前所有活动事务中最小的 SCN",用于一致性读和 Undo 清理。为了推进这个值,系统会扫描 Undo 段中的事务表(UNDO$)。

当扫描过程中耗时过长(例如因为 Undo 段中存在大量未清理的事务槽,或者系统 I/O 缓慢),MMON 的扫描操作就会触发 ORA-12751,并在告警日志中记录:

复制代码
minact-scn: useg scan erroring out with error e:12751

关键点:这条告警不是 数据库损坏的标志,而是系统负载过高或 Undo 管理出现瓶颈的强烈信号。

2.3 两者的关系

告警内容 所属模块 根本原因
ORA-12751: cpu time or run time policy violation MMON 通用 任何 MMON 操作超时
minact-scn: useg scan erroring out with error e:12751 Undo 段扫描 扫描 Undo 事务表耗时过长,触发 ORA-12751

因此,minact-scn 告警是 ORA-12751 的一个子集特定场景


3 内部机制详解(Oracle 19.29)

3.1 隐藏参数与阈值

以下隐藏参数控制 MMON 操作的超时行为(不建议手动修改,除非得到 Oracle 支持明确指示):

参数名 默认值(19c) 作用
_mmon_cpu_time_limit 60 秒 单个 MMON 动作允许的最大 CPU 时间
_mmon_runtime_limit 300 秒 单个 MMON 动作允许的最大挂钟时间
_mmon_suspend_timeout 82800 秒(23 小时) 当动作反复失败后,MMON 挂起该动作的时间
_mmon_awr_snapshot_timeout 300 秒 AWR 快照生成超时时间

查看这些隐藏参数的当前值

命令

复制代码
SELECT ksppinm, ksppstvl, ksppdesc
FROM x$ksppi x, x$ksppsv y
WHERE x.indx = y.indx AND ksppinm LIKE '%mmon%';

示例输出

复制代码
KSPPINM                        KSPPSTVL   KSPPDESC
------------------------------ ---------- --------------------------------------------------
_mmon_cpu_time_limit           60         maximum cpu time (seconds) for a MMON action
_mmon_runtime_limit            300        maximum run time (seconds) for a MMON action
_mmon_suspend_timeout          82800      time in seconds to suspend MMON action after failure
_mmon_awr_snapshot_timeout     300        timeout for AWR snapshot generation
_mmon_auto_awr_timeout         600        timeout for auto AWR flush

3.2 Undo 段扫描(minact-scn)的触发条件

在以下情况下,MMON 会执行 minact-scn 扫描:

  • 数据库启动或实例恢复后

  • 定期推进最小活动 SCN(通常每隔几分钟)

  • 长时间运行的事务提交或回滚后,需要清理 Undo 空间

扫描过程中,MMON 会遍历 UNDO$ 基表中的所有 Undo 段,检查每个段的事务表,计算最小的活动 SCN。如果 Undo 段数量巨大(例如上千个)或者每个段的事务槽占用率高,扫描就会耗时很长,容易触发 ORA-12751。

3.3 与系统负载的关系

重要结论(来自 KB86914):

"The messages are an indication of high load on the system as opposed to the cause of the problem."

即:minact-scn: useg scan erroring out with error e:12751系统高负载的结果,而不是根本原因。它提示 DBA 去检查:

  • CPU 是否过载

  • I/O 是否缓慢

  • 是否存在大量 Undo 生成(例如大批量更新、长事务)

  • 是否存在锁竞争或 Row Cache 争用


4 完整排查流程(命令 + 示例输出)

4.1 第一步:确认告警日志中的信息

方法一:使用 ADRCI 工具

命令

复制代码
adrci
> set homepath diag/rdbms/orcl/orcl
> show alert -p "message_text like '%ORA-12751%' or message_text like '%minact-scn%'" -tail 500

示例输出

复制代码
ADRCI: Release 19.0.0.0.0 - Production on Wed Apr 9 14:32:15 2026

Copyright (c) 1982, 2026, Oracle and/or its affiliates.  All rights reserved.

ADR base = "/u01/app/oracle"

adrci> set homepath diag/rdbms/orcl/orcl
adrci> show alert -p "message_text like '%ORA-12751%' or message_text like '%minact-scn%'" -tail 500

2026-04-09 03:15:22.123 +08:00
minact-scn: useg scan erroring out with error e:12751
2026-04-09 03:20:35.456 +08:00
minact-scn: useg scan erroring out with error e:12751
2026-04-09 03:25:10.789 +08:00
Errors in file /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_mmon_12345.trc:
ORA-12751: cpu time or run time policy violation
2026-04-09 03:30:02.001 +08:00
Suspending MMON action 'AWR Auto Purge Task' for 82800 seconds
方法二:直接查询 ADR 中的告警视图(SQL)

命令

复制代码
SELECT originating_timestamp, message_text
FROM v$diag_alert_ext
WHERE message_text LIKE '%ORA-12751%' OR message_text LIKE '%minact-scn%'
ORDER BY originating_timestamp DESC
FETCH FIRST 20 ROWS ONLY;

示例输出

复制代码
ORIGINATING_TIMESTAMP          MESSAGE_TEXT
------------------------------ ------------------------------------------------------------
09-APR-26 03.25.10.789000 AM   Errors in file .../orcl_mmon_12345.trc: ORA-12751: cpu time...
09-APR-26 03.20.35.456000 AM   minact-scn: useg scan erroring out with error e:12751
09-APR-26 03.15.22.123000 AM   minact-scn: useg scan erroring out with error e:12751

4.2 第二步:判断数据库整体健康状况

在深入分析具体错误之前,必须先排除系统级性能问题。

4.2.1 检查平均活动会话(AAS)

命令

复制代码
SELECT end_time, avg_active_sessions
FROM v$sysmetric_history
WHERE metric_name = 'Average Active Sessions'
  AND end_time > SYSDATE - 30/1440
ORDER BY end_time;

示例输出

复制代码
END_TIME                 AVG_ACTIVE_SESSIONS
------------------------ -------------------
09-APR-26 02.00.00.000 PM                   5.2
09-APR-26 02.05.01.000 PM                   6.1
09-APR-26 02.10.00.000 PM                   8.4
09-APR-26 02.15.00.000 PM                  12.7   <- 负载升高
09-APR-26 02.20.01.000 PM                  15.3   <- 严重过载
09-APR-26 02.25.00.000 PM                  14.9

如果 AAS 持续超过 CPU 核心数(例如 8 核 CPU,AAS > 16),说明系统严重过载。

4.2.2 检查当前等待事件(实时)

命令

复制代码
SELECT event, COUNT(*) AS session_count
FROM v$session
WHERE wait_class != 'Idle'
GROUP BY event
ORDER BY session_count DESC
FETCH FIRST 10 ROWS ONLY;

示例输出

复制代码
EVENT                                         SESSION_COUNT
--------------------------------------------- -------------
gc buffer busy                                           42
buffer busy waits                                        28
log file sync                                            15
read by other session                                    12
enq: TX - row lock contention                            10
db file sequential read                                   8
db file scattered read                                    7
control file sequential read                              5
log buffer space                                          3
latch: cache buffers chains                               2
4.2.3 检查系统 CPU 使用率

命令

复制代码
SELECT metric_name, value
FROM v$sysmetric
WHERE metric_name IN ('CPU Usage Per Sec', 'CPU Usage Per User')
  AND group_id = 2;

示例输出

复制代码
METRIC_NAME             VALUE
----------------------- ----------
CPU Usage Per Sec       78.2
CPU Usage Per User      12.5

如果 CPU Usage Per Sec 持续超过 80,表明 CPU 紧张。

4.2.4 检查系统负载总体趋势

命令

复制代码
SELECT begin_time, end_time, intsize_csec, 
       avg_active_sessions, cpu_usage_per_sec, iowait_per_sec
FROM v$sysmetric_summary
WHERE metric_name IN ('Average Active Sessions', 'CPU Usage Per Sec', 'I/O Wait Per Sec')
AND begin_time > SYSDATE - 1
ORDER BY begin_time;

示例输出

复制代码
BEGIN_TIME          END_TIME            INTSIZE_CSEC AVG_ACTIVE_SESSIONS CPU_USAGE_PER_SEC IOWAIT_PER_SEC
------------------- ------------------- ------------- ------------------- ----------------- --------------
09-APR-26 12.00.00 09-APR-26 12.15.00            900                 4.2              45.3            2.1
09-APR-26 12.15.00 09-APR-26 12.30.00            900                 8.1              72.8            5.6
09-APR-26 12.30.00 09-APR-26 12.45.00            900                14.3              89.2           12.4  <- I/O 等待升高
09-APR-26 12.45.00 09-APR-26 13.00.00            900                18.7              95.1           18.9

4.3 第三步:分析 MMON 跟踪文件

MMON 跟踪文件通常位于 $ADR_HOME/trace/,命名模式为 *_mmon_*.trc*_m000_*.trc

4.3.1 定位最新的 MMON 跟踪文件

命令(SQL)

复制代码
SELECT name, modification_time, size/1024/1024 AS size_mb
FROM v$diag_trace_file
WHERE (name LIKE '%mmon%' OR name LIKE '%m000%')
  AND modification_time > SYSDATE - 1
ORDER BY modification_time DESC;

示例输出

复制代码
NAME                                                       MODIFICATION_TIME      SIZE_MB
---------------------------------------------------------- ---------------------- ----------
orcl_mmon_12345.trc                                        09-APR-26 03.25.10.000      4.2
orcl_m000_23456.trc                                        09-APR-26 03.20.01.000      2.1
orcl_mmon_12345.trc                                        09-APR-25 22.10.05.000      3.8
4.3.2 在跟踪文件中搜索 ORA-12751 及 Undo 扫描相关信息

操作系统命令(假设已进入 trace 目录):

复制代码
cd /u01/app/oracle/diag/rdbms/orcl/orcl/trace
grep -i "ORA-12751\|minact-scn\|Block Cleanout\|Undo Segment" *_mmon*.trc

示例输出

复制代码
orcl_mmon_12345.trc: KEWROCISTMTEXEC - encountered error: (ORA-20011: Approximate NDV failed: ORA-12751: cpu time or run time policy violation)
orcl_mmon_12345.trc: ORA-06512: at "SYS.DBMS_STATS", line 24281
orcl_mmon_12345.trc: KEBM: MMON action policy violation. 'Block Cleanout Optim, Undo Segment Scan' viol=1; err=12751
orcl_mmon_12345.trc: *** 2026-04-09T03:25:10.789123+08:00
orcl_mmon_12345.trc: ORA-12751: cpu time or run time policy violation
4.3.3 从 SQL 中直接查看跟踪文件的部分内容(使用 V$DIAG_TRACE_FILE_CONTENTS

命令

复制代码
SELECT payload
FROM v$diag_trace_file_contents
WHERE trace_filename = 'orcl_mmon_12345.trc'
  AND (payload LIKE '%ORA-12751%' OR payload LIKE '%Block Cleanout%')
  AND rownum <= 20;

示例输出

复制代码
PAYLOAD
--------------------------------------------------------------------------------
KEWROCISTMTEXEC - encountered error: (ORA-20011: Approximate NDV failed: ORA-12751: cpu time or run time policy violation
ORA-06512: at "SYS.DBMS_STATS", line 24281
ORA-06512: at "SYS.DBMS_STATS", line 24332
)
KEBM: MMON action policy violation. 'Block Cleanout Optim, Undo Segment Scan' viol=1; err=12751
DDE actions executed for ORA-12751

4.4 第四步:检查 Undo 表空间与事务状态

4.4.1 查看 Undo 表空间使用率

命令

复制代码
SELECT tablespace_name, used_percent, autoextensible
FROM dba_tablespace_usage_metrics
WHERE tablespace_name LIKE '%UNDO%';

示例输出

复制代码
TABLESPACE_NAME      USED_PERCENT AUTOEXTENSIBLE
-------------------- ------------ ---------------
UNDOTBS1                     92.3 YES

使用率超过 85% 表示 Undo 表空间紧张,可能引起性能问题。

4.4.2 查看 Undo 生成速率及最长查询(v$undostat

命令

复制代码
SELECT begin_time, end_time,
       maxquerylen AS longest_query_secs,
       tuned_undoretention AS tuned_retention_secs,
       ssolderrcnt AS snapshot_too_old_errors
FROM v$undostat
ORDER BY begin_time DESC
FETCH FIRST 10 ROWS ONLY;

示例输出

复制代码
BEGIN_TIME          END_TIME            LONGEST_QUERY_SECS TUNED_RETENTION_SECS SNAPSHOT_TOO_OLD_ERRORS
------------------- ------------------- ------------------ -------------------- -----------------------
09-APR-26 02.00.00 09-APR-26 02.15.00                2543                 3600                       0
09-APR-26 01.45.00 09-APR-26 02.00.00                2489                 3600                       0
09-APR-26 01.30.00 09-APR-26 01.45.00                2621                 3600                       0
09-APR-26 01.15.00 09-APR-26 01.30.00                2700                 3600                       1
09-APR-26 01.00.00 09-APR-26 01.15.00                2588                 3600                       0

LONGEST_QUERY_SECS 超过 1800 秒(30 分钟)说明存在长查询,会强制 Undo 保留很长时间,增加扫描负担。

4.4.3 查找当前运行中的长事务

命令

复制代码
SELECT sid, serial#, start_time, (SYSDATE - start_time) * 24 AS hours, used_ublk, status
FROM v$transaction
WHERE (SYSDATE - start_time) > 1/24;   -- 超过 1 小时

示例输出

复制代码
SID    SERIAL# START_TIME              HOURS   USED_UBLK STATUS
------ ------- ----------------------- ------- ---------- ------------
142        987 09-APR-26 01:10:23       2.3        12456 ACTIVE
256        321 09-APR-26 00:45:17       3.8        89231 ACTIVE

如果存在长事务,需要与应用确认是否可以终止或提交。

4.4.4 查看 Undo 段的详细状态

命令

复制代码
SELECT n.name, r.extents, r.rssize/1024/1024 AS size_mb, r.status
FROM v$rollstat r, v$rollname n
WHERE r.usn = n.usn
ORDER BY r.extents DESC;

示例输出

复制代码
NAME                           EXTENTS   SIZE_MB STATUS
------------------------------ ---------- ------- ------------
_SYSSMU10_1234567890$                234      567 ONLINE
_SYSSMU9_1234567891$                 198      489 ONLINE
_SYSSMU8_1234567892$                 187      456 ONLINE
_SYSSMU7_1234567893$                 176      432 ONLINE
_SYSSMU6_1234567894$                 165      398 ONLINE
_SYSSMU5_1234567895$                 154      376 ONLINE
_SYSSMU4_1234567896$                 143      354 ONLINE
_SYSSMU3_1234567897$                 132      332 ONLINE
_SYSSMU2_1234567898$                 121      310 ONLINE
_SYSSMU1_1234567899$                 110      288 ONLINE

如果某个 Undo 段的 extents 数量超过 1000,或者 size_mb 异常大(例如 > 10GB),说明 Undo 段过度扩展,可能需要重建 Undo 表空间。

4.5 第五步:检查 Row Cache 争用(关联 KB148634)

KB148634 指出,minact-scn 错误有时与 Row Cache Enqueue Lock 等待有关,尤其是在备份操作期间。

4.5.1 查看 Row Cache 命中率

命令

复制代码
SELECT parameter, gets, getmisses, 
       ROUND((1 - (getmisses / DECODE(gets, 0, 1, gets))) * 100, 2) AS hit_ratio
FROM v$rowcache
WHERE parameter IN ('dc_rollback_segments', 'dc_segments')
  AND gets > 0;

示例输出

复制代码
PARAMETER                     GETS   GETMISSES HIT_RATIO
----------------------- ---------- ---------- ----------
dc_rollback_segments         1234567      54321      95.60
dc_segments                 98765432    1234567      98.75

如果 dc_rollback_segments 的命中率低于 95%,说明 Undo 段相关的行缓存存在争用。

4.5.2 查看当前的锁等待(阻塞链)

命令

复制代码
SELECT * FROM dba_waiters;

示例输出

复制代码
WAITING_SESSION   HOLDING_SESSION   LOCK_TYPE   MODE_HELD   MODE_REQUESTED   LOCK_ID1   LOCK_ID2
---------------- ----------------- ----------- ----------- ---------------- ---------- ----------
              142               256 DML         Row-X       None             12345          0
              256               987 Row Cache   Shared      Exclusive        54321          0

如果看到 Row Cache 类型的锁等待,且资源与 Undo 段相关,则可能是导致 MMON 扫描超时的原因。

4.5.3 查看系统级锁统计

命令

复制代码
SELECT * FROM v$lock WHERE block > 0;

示例输出

复制代码
ADDR             KADDR           SID TY        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK
---------------- ---------------- --- -- ---------- ---------- ---------- ---------- ---------- ----------
0000000123456780 0000000123456798 142 TX      65539      12345          6          0       3456          1
0000000123456800 0000000123456818 256 TA      12345          0          4          0       1234          1

TY='TA' 表示事务锁(Undo 段相关),如果 BLOCK=1 说明存在阻塞。


5 分场景解决方案(命令 + 示例输出)

5.1 场景一:minact-scn 超时 + 系统整体负载高

现象 :告警日志频繁出现 minact-scn: useg scan erroring out with error e:12751,同时系统 CPU 或 I/O 使用率居高不下。

5.1.1 识别 Top SQL(按 CPU 时间)

命令

复制代码
SELECT sql_id, cpu_time/1000000 AS cpu_sec, elapsed_time/1000000 AS elapsed_sec, executions
FROM v$sqlstats
ORDER BY cpu_time DESC
FETCH FIRST 10 ROWS ONLY;

示例输出

复制代码
SQL_ID        CPU_SEC ELAPSED_SEC EXECUTIONS
------------- ------- ----------- ----------
5g7q2k4p1c3n2    1234        5678         12
8h9r0s2t4u6v8     987        4321        345
2a3b4c5d6e7f8     876        3987         56
5.1.2 获取高负载 SQL 的详细文本

命令(以第一个 SQL_ID 为例):

复制代码
SELECT sql_text FROM v$sql WHERE sql_id = '5g7q2k4p1c3n2';

示例输出

复制代码
SQL_TEXT
--------------------------------------------------------------------------------
UPDATE large_table SET status = 'PROCESSED' WHERE created_date < SYSDATE - 30

解决建议 :为该 SQL 创建索引(例如在 created_date 上),或拆分批量更新。

5.1.3 增加 Undo 表空间大小并启用自动扩展

命令

复制代码
-- 先查看现有数据文件
SELECT file_name, bytes/1024/1024 AS size_mb, autoextensible
FROM dba_data_files WHERE tablespace_name = 'UNDOTBS1';

-- 添加新数据文件(10G,自动扩展)
ALTER TABLESPACE undotbs1 ADD DATAFILE '/u01/app/oracle/oradata/orcl/undotbs2.dbf' SIZE 10G AUTOEXTEND ON NEXT 1G MAXSIZE 32G;

-- 或者扩展现有文件
ALTER DATABASE DATAFILE '/u01/app/oracle/oradata/orcl/undotbs1.dbf' RESIZE 20G;

示例输出(添加文件成功):

复制代码
Tablespace altered.
5.1.4 调整 Undo 保留时间(如果 tuned_undoretention 过大)

命令

复制代码
-- 查看当前设置
SHOW PARAMETER undo_retention;

-- 设置为 15 分钟(900 秒)
ALTER SYSTEM SET undo_retention=900 SCOPE=BOTH;

示例输出

复制代码
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_retention                       integer     900
System altered.
5.1.5 如果问题由备份引起(参考 KB148634)

在 RMAN 备份脚本中添加参数以减轻 Undo 扫描压力:

RMAN 命令示例

复制代码
rman target /
CONFIGURE DEVICE TYPE DISK PARALLELISM 2;
BACKUP INCREMENTAL LEVEL 0 DATABASE SECTION SIZE 4G;

示例输出

复制代码
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=142 device type=DISK
Starting backup at 09-APR-26
channel ORA_DISK_1: starting compressed incremental level 0 datafile backup set
channel ORA_DISK_1: specifying datafile(s) for backup
...
Finished backup at 09-APR-26

5.2 场景二:minact-scn 超时 + 存在长事务或长查询

现象v$undostat.maxquerylen 数值很大(例如超过 2 小时),v$transaction 中存在运行很久的事务。

5.2.1 终止长事务(需业务确认)

命令

复制代码
-- 先获取 SID, SERIAL#
SELECT sid, serial#, start_time, used_ublk
FROM v$transaction;

-- 终止会话
ALTER SYSTEM KILL SESSION '142,987' IMMEDIATE;

示例输出

复制代码
System altered.
5.2.2 优化长查询:通过 SQL Monitor 查看执行计划

命令

复制代码
SELECT dbms_sqltune.report_sql_monitor(sql_id => '5g7q2k4p1c3n2', type => 'TEXT') AS report
FROM dual;

示例输出(节选):

复制代码
SQL Monitoring Report

SQL_ID: 5g7q2k4p1c3n2
-----------------------------------------
| Elapsed: 5678s | CPU: 1234s | IO: 4000s |
-----------------------------------------
Plan:
---------------------------------------------------------
| Id | Operation         | Name       | Rows | Cost |
---------------------------------------------------------
| 0  | UPDATE            | LARGE_TABLE| 10M  | 500K |
| 1  |  TABLE ACCESS FULL| LARGE_TABLE| 10M  | 500K |
---------------------------------------------------------
...

全表扫描,建议在 created_date 上创建索引。

5.2.3 如果无法终止,考虑拆分事务(应用层改造)

此步骤无直接 SQL 命令,需开发配合。示例:将单次更新 1000 万行拆分为每次 1 万行并提交。

5.3 场景三:minact-scn 超时 + Row Cache 争用

现象v$rowcachedc_rollback_segments 的命中率极低,且 v$lock 中存在 TA 类型的锁等待。

5.3.1 临时增加 Row Cache 大小(需重启)

命令

复制代码
-- 查看当前 shared_pool_size
SHOW PARAMETER shared_pool_size;

-- 增加 shared_pool_size(例如从 4G 增加到 8G)
ALTER SYSTEM SET shared_pool_size=8G SCOPE=SPFILE;
-- 重启数据库
SHUTDOWN IMMEDIATE;
STARTUP;

示例输出

复制代码
System altered.
Database closed.
Database dismounted.
ORACLE instance shut down.
ORACLE instance started.
...
Database mounted.
Database opened.
5.3.2 检查是否有频繁的 Undo 段扩展/收缩

命令

复制代码
SELECT name, extents, rssize/1024/1024 AS size_mb, status, hwmsize/1024/1024 AS hwm_mb
FROM v$rollstat r, v$rollname n
WHERE r.usn = n.usn
ORDER BY extents DESC;

示例输出

复制代码
NAME                           EXTENTS   SIZE_MB STATUS   HWM_MB
------------------------------ ---------- ------- -------- -------
_SYSSMU10_1234567890$               234      567 ONLINE      580
_SYSSMU9_1234567891$               1234     2890 ONLINE     2950  <- 异常高
...

如果 extents 数量超过 1000,建议重建 Undo 表空间。

重建 Undo 表空间步骤

复制代码
-- 创建新的 Undo 表空间
CREATE UNDO TABLESPACE undotbs2 DATAFILE SIZE 10G AUTOEXTEND ON NEXT 1G MAXSIZE 32G;

-- 切换至新 Undo 表空间
ALTER SYSTEM SET undo_tablespace=undotbs2 SCOPE=BOTH;

-- 等待旧 Undo 表空间无活动事务后删除
DROP TABLESPACE undotbs1 INCLUDING CONTENTS AND DATAFILES;
5.3.3 应用补丁(如果版本低于 19.20)

命令(查看当前版本)

复制代码
SELECT banner_full FROM v$version;

示例输出

复制代码
BANNER_FULL
--------------------------------------------------------------------------------
Oracle Database 19c Enterprise Edition Release 19.11.0.0.0 - Production
Version 19.11.0.0.0

若版本低于 19.20,建议升级到 19.29 以修复相关 Bug(如 Bug 21696340)。

5.4 场景四:minact-scn 超时 + 无其他明显负载异常

现象 :告警日志有错误,但系统性能正常,v$session 无异常等待。

5.4.1 收集诊断信息(使用第 8 节的完整脚本)

(脚本在第 8 节给出,此处先提供手动收集关键信息)

命令

复制代码
-- 导出当前 Undo 配置
SHOW PARAMETER undo;

-- 导出最近 1 小时 AWR 快照列表
SELECT snap_id, begin_interval_time FROM dba_hist_snapshot WHERE begin_interval_time > SYSDATE - 1/24;

示例输出

复制代码
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_management                      string      AUTO
undo_retention                       integer     900
undo_tablespace                      string      UNDOTBS1

   SNAP_ID BEGIN_INTERVAL_TIME
---------- ----------------------------------------
     52345 09-APR-26 01.00.00.000000000 PM
     52346 09-APR-26 02.00.00.000000000 PM
     52347 09-APR-26 03.00.00.000000000 PM
5.4.2 手动强制推进 minact-scn(仅限测试,慎用)

命令

复制代码
-- 开启内部事件 10511(加速 Undo 段扫描)
ALTER SYSTEM SET EVENTS '10511 trace name context forever, level 1';

-- 等待 10 分钟(观察告警日志是否减少)
-- 关闭事件
ALTER SYSTEM SET EVENTS '10511 trace name context off';

示例输出

复制代码
System altered.
System altered.

注意:此操作会增加 CPU 开销,仅建议在非生产环境或 Oracle 支持指导下使用。

5.4.3 如果问题持续,联系 Oracle 支持并提供以下文件

所需文件列表:

  • 告警日志(包含错误出现前后 1 小时)

  • MMON 跟踪文件(*_mmon*.trc

  • AWR 报告(如果能生成)

  • v$undostatv$rollstat 输出(上面已收集)

生成 AWR 报告的命令

复制代码
-- 找出最近两次快照 ID
SELECT snap_id, begin_interval_time FROM dba_hist_snapshot ORDER BY snap_id DESC FETCH FIRST 2 ROWS ONLY;

-- 生成 HTML 报告
SELECT output FROM TABLE(dbms_workload_repository.awr_report_html(12345, 12346));

(输出内容过长,此处省略)


6 通用解决方案:针对 ORA-12751 的总体策略

无论触发场景如何,以下通用措施可有效缓解或解决 ORA-12751。

6.1 调整 AWR 快照频率与保留期

命令

复制代码
-- 查看当前 AWR 设置
SELECT * FROM dba_hist_wr_control;

-- 将快照间隔从默认的 60 分钟改为 120 分钟(减少 MMON 负担)
-- 保留期改为 7 天(10080 分钟)
BEGIN
  DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS(
    interval => 120,
    retention => 7*24*60
  );
END;
/

示例输出

复制代码
DBID      SNAP_INTERVAL        RETENTION            TOPNSQL
---------- -------------------- -------------------- ----------
123456789 +00000 02:00:00.0     +00007 00:00:00.0     DEFAULT

PL/SQL procedure successfully completed.

6.2 优化统计信息收集

命令

复制代码
-- 查看当前全局统计信息偏好
SELECT dbms_stats.get_prefs('DEGREE') AS degree FROM dual;
SELECT dbms_stats.get_prefs('APPROXIMATE_NDV') AS approx_ndv FROM dual;

-- 降低自动统计信息收集的并行度(从默认的 `AUTO_DEGREE` 改为固定 4)
EXEC DBMS_STATS.SET_GLOBAL_PREFS('DEGREE', '4');

-- 关闭近似 NDV(如果该功能导致超时,临时关闭)
EXEC DBMS_STATS.SET_GLOBAL_PREFS('APPROXIMATE_NDV', 'FALSE');

示例输出

复制代码
DEGREE
--------------------------------------------------------------------------------
AUTO_DEGREE

APPROX_NDV
--------------------------------------------------------------------------------
TRUE

PL/SQL procedure successfully completed.
PL/SQL procedure successfully completed.

6.3 调整隐藏参数(最后手段,需重启)

警告:仅当所有其他方法均无效且 Oracle 支持明确建议时使用。

命令

复制代码
-- 查看当前隐藏参数值(前面已做)
-- 修改参数
ALTER SYSTEM SET "_mmon_runtime_limit"=900 SCOPE=SPFILE;
ALTER SYSTEM SET "_mmon_cpu_time_limit"=180 SCOPE=SPFILE;

-- 重启数据库
SHUTDOWN IMMEDIATE;
STARTUP;

-- 确认修改生效
SELECT ksppinm, ksppstvl FROM x$ksppi x, x$ksppsv y
WHERE x.indx = y.indx AND ksppinm IN ('_mmon_runtime_limit','_mmon_cpu_time_limit');

示例输出

复制代码
System altered.
System altered.
Database closed.
Database dismounted.
ORACLE instance shut down.
ORACLE instance started.
...
Database opened.

KSPPINM                        KSPPSTVL
------------------------------ ----------
_mmon_cpu_time_limit           180
_mmon_runtime_limit            900

6.4 收集错误栈以便深入分析

命令

复制代码
-- 开启针对 ORA-12751 的错误栈追踪(级别 3)
ALTER SYSTEM SET EVENTS '12751 trace name errorstack level 3';

-- 等待错误再次出现(通常会在下一次 MMON 动作时)
-- 查看生成的 trace 文件位置
SELECT value FROM v$diag_info WHERE name = 'Diag Trace';

-- 关闭错误栈追踪
ALTER SYSTEM SET EVENTS '12751 trace name errorstack off';

示例输出

复制代码
System altered.

VALUE
--------------------------------------------------------------------------------
/u01/app/oracle/diag/rdbms/orcl/orcl/trace

System altered.

在 trace 文件中生成的错误栈示例 (使用 grep 查看):

复制代码
grep -A 20 "ksedmp" /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_12345.trc

示例输出节选:

复制代码
----- Call Stack Trace -----
ksedmp <- ksdpec <- ksfpec <- kgevpm <- kgewpr <- kpeDbgDDEHandleError
<- kpeDbgDDEHandleError <- kpebdde <- kpebmmone <- kpebmmone <- ksbrdp
<- opirip <- opidrv <- sou2o <- opimai_real <- main <- __libc_start_main

7 预防措施与长效监控

7.1 日常监控项与告警阈值

监控对象 指标 告警阈值 频率 监控命令
Undo 表空间 使用率 > 85% 每小时 SELECT used_percent FROM dba_tablespace_usage_metrics WHERE tablespace_name LIKE '%UNDO%';
最长查询时间 maxquerylen > 1800 秒 每小时 SELECT maxquerylen FROM v$undostat ORDER BY begin_time DESC FETCH FIRST 1 ROW ONLY;
AWR 快照连续性 相邻快照间隔 > 1.5 小时 每小时 见下方脚本
MMON 错误 告警日志中 ORA-12751 任何出现 实时 见下方触发器
Row Cache 命中率 dc_rollback_segments < 95% 每天 SELECT hit_ratio FROM v$rowcache WHERE parameter='dc_rollback_segments';

7.2 自动化监控脚本示例

7.2.1 检查 AWR 快照连续性

命令 (保存为 check_awr_gap.sql):

复制代码
WITH snap_gap AS (
  SELECT snap_id, begin_interval_time,
         LAG(begin_interval_time) OVER (ORDER BY snap_id) AS prev_begin
  FROM dba_hist_snapshot
  WHERE begin_interval_time > SYSDATE - 1
)
SELECT 'GAP_FOUND' AS status, (begin_interval_time - prev_begin) * 24 AS hours_gap
FROM snap_gap
WHERE (begin_interval_time - prev_begin) > 1.5/24;

示例输出(无间隙时):

复制代码
STATUS     HOURS_GAP
---------- ----------
(no rows)

示例输出(有间隙时):

复制代码
STATUS     HOURS_GAP
---------- ----------
GAP_FOUND        2.3
7.2.2 创建数据库事件触发器自动记录 ORA-12751

命令

复制代码
-- 创建记录表
CREATE TABLE dba_ora12751_log (
  occur_time TIMESTAMP,
  error_code NUMBER,
  error_msg VARCHAR2(4000)
);

-- 创建触发器
CREATE OR REPLACE TRIGGER trg_capture_ora12751
AFTER SERVERERROR ON DATABASE
DECLARE
  v_error_msg VARCHAR2(4000);
BEGIN
  IF (IS_SERVERERROR(12751)) THEN
    SELECT message_text INTO v_error_msg
    FROM v$diag_alert_ext
    WHERE ROWNUM = 1
    ORDER BY originating_timestamp DESC;
    INSERT INTO dba_ora12751_log VALUES (SYSTIMESTAMP, 12751, v_error_msg);
    COMMIT;
  END IF;
END;
/

示例输出

复制代码
Table created.

Trigger created.

验证触发器(模拟错误无法直接触发,但可检查触发器状态):

复制代码
SELECT trigger_name, status FROM user_triggers WHERE trigger_name = 'TRG_CAPTURE_ORA12751';

示例输出:

复制代码
TRIGGER_NAME                   STATUS
------------------------------- --------
TRG_CAPTURE_ORA12751            ENABLED

7.3 版本与补丁建议

  • 最低推荐版本:Oracle 19.9.0.0(修复了大量 MMON 相关 Bug)

  • 最佳版本:19.29.0.0(截至 2026 年 4 月的最新补丁集)

  • 关键补丁

    • Patch 29644286: Fix for ORA-12751 in DBMS_FEATURE_USAGE_INTERNAL

    • Patch 32124507: Fix for ORA-12751 in DBMS_STATS

    • Patch 21696340: Row cache lock contention on dc_rollback_segments

查看当前已应用的补丁

复制代码
$ORACLE_HOME/OPatch/opatch lsinventory

示例输出(节选):

复制代码
Oracle Home       : /u01/app/oracle/product/19.0.0/dbhome_1
Inventory         : /u01/app/oraInventory
Patch Set         : 19.0.0.0.0
Patch ID          : 35037840
Applied Patches   : 35037840, 34533061, 34061764

8 完整诊断脚本(一键收集)

将以下内容保存为 diag_ora12751_minact.sql,以 SYSDBA 执行:

复制代码
SET ECHO OFF FEEDBACK OFF TERMOUT OFF
COLUMN output FORMAT A200
SPOOL diag_ora12751_$(date +%Y%m%d_%H%M%S).log

PROMPT ==================== 1. Alert Log ORA-12751/minact-scn ====================
SELECT message_text FROM v$diag_alert_ext
WHERE message_text LIKE '%ORA-12751%' OR message_text LIKE '%minact-scn%'
ORDER BY originating_timestamp DESC FETCH FIRST 50 ROWS ONLY;

PROMPT ==================== 2. Current System Load ====================
SELECT * FROM v$sysmetric WHERE metric_name IN ('CPU Usage Per Sec', 'Database Time Per Sec', 'Average Active Sessions');

PROMPT ==================== 3. Top 10 Wait Events (System-wide) ====================
SELECT event, total_waits, time_waited_micro/1000000 AS sec_waited
FROM v$system_event WHERE wait_class != 'Idle' ORDER BY time_waited_micro DESC FETCH FIRST 10 ROWS ONLY;

PROMPT ==================== 4. Current Session Wait Events ====================
SELECT event, COUNT(*) AS session_count
FROM v$session WHERE wait_class != 'Idle' GROUP BY event ORDER BY session_count DESC FETCH FIRST 10 ROWS ONLY;

PROMPT ==================== 5. Undo Statistics (Last 10 intervals) ====================
SELECT begin_time, maxquerylen, tuned_undoretention, ssolderrcnt
FROM v$undostat ORDER BY begin_time DESC FETCH FIRST 10 ROWS ONLY;

PROMPT ==================== 6. Long Running Transactions (>1 hour) ====================
SELECT sid, serial#, start_time, (SYSDATE-start_time)*24 AS hours, used_ublk
FROM v$transaction WHERE (SYSDATE-start_time) > 1/24;

PROMPT ==================== 7. Undo Segments Status ====================
SELECT n.name, r.extents, r.rssize/1024/1024 AS size_mb, r.status
FROM v$rollstat r, v$rollname n WHERE r.usn = n.usn ORDER BY r.extents DESC;

PROMPT ==================== 8. Row Cache Hit Ratio (dc_rollback_segments) ====================
SELECT parameter, (gets-getmisses)/DECODE(gets,0,1,gets)*100 AS hit_ratio
FROM v$rowcache WHERE parameter LIKE 'dc_rollback%';

PROMPT ==================== 9. MMON Trace Files (Last 7 Days) ====================
SELECT name, modification_time FROM v$diag_trace_file
WHERE (name LIKE '%mmon%' OR name LIKE '%m000%') AND modification_time > SYSDATE-7
ORDER BY modification_time DESC;

PROMPT ==================== 10. Hidden MMON Parameters ====================
SELECT ksppinm, ksppstvl, ksppdesc FROM x$ksppi x, x$ksppsv y
WHERE x.indx = y.indx AND ksppinm LIKE '%mmon%';

PROMPT ==================== 11. AWR Snapshot Gaps (Last 24h) ====================
WITH snap_gap AS (
  SELECT snap_id, begin_interval_time,
         LAG(begin_interval_time) OVER (ORDER BY snap_id) AS prev_begin
  FROM dba_hist_snapshot
  WHERE begin_interval_time > SYSDATE - 1
)
SELECT * FROM snap_gap
WHERE (begin_interval_time - prev_begin) > 1.5/24;

PROMPT ==================== 12. Current Database Version ====================
SELECT banner_full FROM v$version;

PROMPT ==================== 13. Undo Tablespace Usage ====================
SELECT tablespace_name, used_percent, autoextensible
FROM dba_tablespace_usage_metrics
WHERE tablespace_name LIKE '%UNDO%';

SPOOL OFF
PROMPT Diagnostic completed. Check the spool file diag_ora12751_*.log

执行命令

复制代码
sqlplus / as sysdba @diag_ora12751_minact.sql

示例输出(脚本运行时的屏幕输出)

复制代码
SQL> @diag_ora12751_minact.sql
PROMPT Diagnostic completed. Check the spool file diag_ora12751_20260409_153022.log

生成的日志文件内容示例(节选):

复制代码
==================== 1. Alert Log ORA-12751/minact-scn ====================
MESSAGE_TEXT
--------------------------------------------------------------------------------
minact-scn: useg scan erroring out with error e:12751
minact-scn: useg scan erroring out with error e:12751
Errors in file .../orcl_mmon_12345.trc: ORA-12751: cpu time or run time policy violation

==================== 5. Undo Statistics ====================
BEGIN_TIME          MAXQUERYLEN TUNED_UNDORETENTION SSOLDERRCNT
------------------- ----------- ------------------- ------------
09-APR-26 02.00.00        2543                3600            0
09-APR-26 01.45.00        2489                3600            0
...

9 总结

9.1 核心要点回顾

  • ORA-12751 是 Oracle 内部管理任务超时的保护机制,不是根因,而是系统存在更深层问题的指示器。

  • minact-scn: useg scan erroring out with error e:12751 是 ORA-12751 在 Undo 段扫描场景下的具体表现,不是数据库损坏,而是系统高负载或 Undo 瓶颈的强烈信号。

  • 排查时先整体后局部:检查系统负载、等待事件、Undo 使用情况、长事务,再分析 MMON 跟踪文件。

  • 解决方案包括:优化 SQL、增加 Undo 表空间、调整 AWR 设置、优化统计信息收集、必要时应用补丁或调整隐藏参数。

  • 预防措施:监控 Undo 表空间使用率、AWR 快照连续性、长查询,并保持数据库版本为 19.29 或更高

9.2 行动路线图(决策树)

当遇到 minact-scn: useg scan erroring out with error e:12751 时:

9.3 最终建议

  • 不要忽视:每次出现 ORA-12751 都应记录并分析,避免掩盖真实性能问题。

  • 主动预防:使用第 7 节的监控脚本,在问题发生前识别风险。

  • 版本管理:始终保持在 Oracle 19.29 或最新的 RU(Release Update)级别。

  • 文档留存:将每次排查过程及解决方案归档,形成知识库。

通过本文的系统性指导,您应该能够从容应对 ORA-12751 及其相关的 minact-scn 告警,确保 Oracle 19.29 数据库的稳定运行。

文档版本 :1.0
整合自 :Oracle KB145377, KB86914, KB148634, KB126507
适用版本 :Oracle Database 19.29+
最后更新 :2026-04-13
示例输出基于:Oracle 19.29 模拟环境

相关推荐
星晨雪海2 小时前
优惠券秒杀的核心业务逻辑
java·前端·数据库
清风6666662 小时前
基于单片机的智能门控制系统设计与故障报警实现
数据库·单片机·mongodb·毕业设计·课程设计·期末大作业
SelectDB技术团队2 小时前
AI 成为主流负载后,数据基础设施将如何演进?|Apache Doris 2026 Roadmap
数据库·人工智能·apache doris·selectdb
SPC的存折2 小时前
分布式(加一键部署脚本)LNMP-Redis-Discuz5.0部署指南-小白详细版
linux·运维·服务器·数据库·redis·分布式·缓存
脑子加油站2 小时前
Redis数据库基础
数据库·redis·缓存
知识分享小能手2 小时前
MongoDB入门学习教程,从入门到精通,MongoDB监控完全指南(22)
数据库·学习·mongodb
℡終嚸♂6802 小时前
SQL 注入与 ThinkPHP 漏洞技术讲义
数据库·sql
杰克尼2 小时前
redis(day07-Redis 最佳实践)
数据库·redis·缓存
倔强的石头1062 小时前
表空间自动目录创建与存储管理实践:参数化配置与性能优化
数据库·oracle·性能优化