Oracle 12c MMON_SLAVE 频繁报 ORA-12850 根因分析与修复方案
一次由 Oracle Bug 24554937 引发的诊断记录。从 trace 文件中的一行报错,到定位根因、再到选择最优修复方案,完整复盘整个排查思路。
一、问题现象
某天巡检时,在 alert log 中发现如下报错:
Errors in file /u01/app/oracle/diag/rdbms/xxdb/xxdb1/trace/xxdb1_m000_11111.trc:
ORA-12850: Could not allocate slaves on all specified instances: 2 needed, 0 allocated
进一步查看 trace 文件,关键信息如下:
| 字段 | 值 |
|---|---|
| 数据库版本 | Oracle 12.1.0.2 |
| 进程类型 | MMON_SLAVE (M000) |
| Action Name | Automatic Report Flush |
| SQL 特征 | WITH MONITOR_DATA AS (SELECT ... |
| 错误代码 | ORA-12850 |
这是一个后台进程报错,没有直接的业务 SQL 触发,但 alert log 中频繁出现,说明 MMON 的某个定时任务在执行时失败了。
二、分析思路
Step 1:确认报错主体
从 trace 文件可以看到:
Oracle process number: 287Unix process pid: 11111, image: oracle@xxdb1 (M000)
M000 是 MMON_SLAVE 进程,属于 MMON(Manageability Monitor)的从属进程,负责执行各种自动化的监控和统计任务。
Step 2:确认触发动作
Trace 中 ACTION NAME: (Automatic Report Flush) 明确指出了触发动作——自动报告刷新。
这是 Oracle 12.1 引入的新特性:Automatic Report Capturing。MMON 会定期查询 GV$SQL_MONITOR 等视图,自动捕获资源消耗较大的 SQL 执行报告,用于后续的性能分析。
Step 3:分析 SQL 内容
从 trace 的内存 dump 中可以看到 SQL 片段:
WITH MONITOR_DATA AS (
SELECT ...
FROM ...
)
这是一个典型的 SQL Monitor 自动捕获查询,以 CTE(Common Table Expression)形式组织,用于汇总跨实例的 SQL 执行监控数据。
Step 4:匹配已知 Bug
在MOS文档中,ORA-12850相关的BUG是比较多的,如何能较精确的匹配上是哪个BUG,需将以下特征组合起来:
- 版本:12.1.0.2
- 进程:MMON_SLAVE
- SQL 语句:WITH MONITOR_DATA AS (…
- 错误:ORA-12850(无法分配 PX Slave)
这些特征与 Oracle Bug 24554937 完全吻合。MOS 上对该 Bug 的描述明确指出:
MMON SQL with SQLID “dfffkcnqfystw” fails with ORA-12850. The SQL text for the SQLID will start with the following similar pattern: ‘WITH MONITOR_DATA AS (SELECT …’
结论:基本可以确认就是 Bug 24554937 导致的。
三、根因剖析
3.1 什么是 Automatic Report Capturing?
Oracle 12.1 引入了 Automatic Report Capturing 特性:
- MMON 后台进程定期扫描
GV$SQL_MONITOR - 自动识别资源消耗大的 SQL(CPU、IO、Elapsed Time 等)
- 自动生成 SQL Monitor 报告,保存到 AWR 中
- 方便 DBA 后续通过
DBMS_AUTO_REPORT等包查看历史报告
这个特性本身很有价值,但在 12.1.0.2 的实现中存在缺陷。
3.2 为什么会报 ORA-12850?
ORA-12850: Could not allocate slaves on all specified instances 表示:
- SQL 需要并行执行(Parallel Execution)
- 需要 2 个 PX Slave,但一个都没分配到
- 通常发生在 RAC 环境中,跨实例查询
GV$视图时
根本原因在于:
- MMON 执行的监控 SQL 涉及
GV$SQL_MONITOR,需要跨实例聚合数据 - 优化器在某些情况下会选择 HASH GROUP BY 的执行计划
- 该计划对 PX Slave 的分配要求较高,而 MMON_SLAVE 进程的资源优先级/调度策略导致无法及时获得所需的并行资源
- 最终抛出 ORA-12850,任务失败
四、解决方案
针对此问题,Oracle 提供了多种修复路径,按推荐优先级排列如下:
方案一:应用官方 Patch(最推荐,根治)
Patch 24554937 是 Oracle 针对此 Bug 的正式修复。
- 在 MOS 上可以下载对应平台版本的补丁
- 安装后修复了 MMON 监控 SQL 的执行计划问题
- 优点:彻底修复,不影响任何功能
- 缺点:需要维护窗口,涉及数据库重启(或滚动补丁,视平台而定)
注意:该 Patch 首次包含在 18.1.0 版本中。如果您的环境计划升级,也可通过升级解决。
方案二:禁用 Automatic Report Capturing(临时规避,无需重启)
如果暂时无法打补丁,可以通过隐藏参数禁用该特性,虽然在官方文档《KI44458》中并未提及该方法,可做尝试:
ALTER SYSTEM SET "_report_capture_cycle_time" = 0 SCOPE=BOTH SID='*';
原理:将该参数设为 0,MMON 不再执行自动报告捕获任务,从而避免触发有问题的 SQL。
- 优点:
- 立即生效,无需重启数据库
- 不影响正常的 SQL Monitor 功能(手动开启
/*+ MONITOR */仍然有效) - 无副作用
- 缺点:
- 失去了自动捕获历史 SQL Monitor 报告的能力
- 属于 workaround,非根本修复
方案三:调整 GROUP BY 执行方式(Bug 描述中的 workaround)
在官方文档《KI44458》中提到的 workaround:
ALTER SYSTEM SET "_gby_hash_aggregation_enabled" = FALSE;
原理:禁用 HASH GROUP BY,强制使用 SORT GROUP BY,可能改变执行计划,避免触发 PX Slave 分配问题。
- 优点:可能解决报错
- 缺点:
- 影响全局所有 GROUP BY 操作,可能导致其他 SQL 性能下降
- 隐藏参数,Oracle 不支持随意修改
- 副作用不可控,在生产环境中谨慎使用
五、写在最后
这次排查再次印证了 “从现象到根因,需要结构化分析” 的思路:
- 先看谁报的错(MMON_SLAVE)
- 再看在做什么(Automatic Report Flush)
- 再看做了什么 SQL(WITH MONITOR_DATA)
- 最后匹配已知问题(Bug 24554937)
很多时候,Oracle 的报错并不是"新大陆",而是已经被记录在案的问题。养成先看 trace、再查 MOS 的习惯,能少走很多弯路。

113

被折叠的 条评论
为什么被折叠?



