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 NameAutomatic Report FlushSQL 特征WITH MONITOR_DATA AS (SELECT ...错误代码ORA-12850这是一个后台进程报错没有直接的业务 SQL 触发但 alert log 中频繁出现说明 MMON 的某个定时任务在执行时失败了。二、分析思路Step 1确认报错主体从 trace 文件可以看到Oracle process number: 287Unix process pid: 11111, image: oraclexxdb1 (M000)M000是MMON_SLAVE进程属于 MMONManageability 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 片段WITHMONITOR_DATAAS(SELECT...FROM...)这是一个典型的SQL Monitor 自动捕获查询以 CTECommon Table Expression形式组织用于汇总跨实例的 SQL 执行监控数据。Step 4匹配已知 Bug在MOS文档中ORA-12850相关的BUG是比较多的如何能较精确的匹配上是哪个BUG需将以下特征组合起来版本12.1.0.2进程MMON_SLAVESQL 语句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 CapturingOracle 12.1 引入了Automatic Report Capturing特性MMON 后台进程定期扫描GV$SQL_MONITOR自动识别资源消耗大的 SQLCPU、IO、Elapsed Time 等自动生成 SQL Monitor 报告保存到 AWR 中方便 DBA 后续通过DBMS_AUTO_REPORT等包查看历史报告这个特性本身很有价值但在 12.1.0.2 的实现中存在缺陷。3.2 为什么会报 ORA-12850ORA-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》中并未提及该方法可做尝试ALTERSYSTEMSET_report_capture_cycle_time0SCOPEBOTH SID*;原理将该参数设为 0MMON 不再执行自动报告捕获任务从而避免触发有问题的 SQL。优点立即生效无需重启数据库不影响正常的 SQL Monitor 功能手动开启/* MONITOR */仍然有效无副作用缺点失去了自动捕获历史 SQL Monitor 报告的能力属于 workaround非根本修复方案三调整 GROUP BY 执行方式Bug 描述中的 workaround在官方文档《KI44458》中提到的 workaroundALTERSYSTEMSET_gby_hash_aggregation_enabledFALSE;原理禁用 HASH GROUP BY强制使用 SORT GROUP BY可能改变执行计划避免触发 PX Slave 分配问题。优点可能解决报错缺点影响全局所有 GROUP BY 操作可能导致其他 SQL 性能下降隐藏参数Oracle 不支持随意修改副作用不可控在生产环境中谨慎使用五、写在最后这次排查再次印证了“从现象到根因需要结构化分析”的思路先看谁报的错MMON_SLAVE再看在做什么Automatic Report Flush再看做了什么 SQLWITH MONITOR_DATA最后匹配已知问题Bug 24554937很多时候Oracle 的报错并不是新大陆而是已经被记录在案的问题。养成先看 trace、再查 MOS 的习惯能少走很多弯路。