我们的 Oracle 服务器出了问题。几个月前它升级到了 11g,并且运行的是第三方系统。该系统已经运行多年(并且还出现了其他几个问题),但这是新问题:每天一两次,CPU 使用率会增加,并且 Cursor Mutex S 非常明显,自服务器启动(最近)以来已经有 3000 万个等待事件。
似乎突然间,许多简单的程序INSERT
开始出现问题。我们已检查统计数据、索引等是否正常 - 是否是最新的、大小是否合适、磁盘空间是否充足等... 都没有问题。
我们已经确定了一个 SQL 表达式是罪魁祸首。许多类似的语句都会导致类似的问题,但我将重点介绍这一个。执行此特定插入的“中间件”软件在大约 70 台服务器上同时运行。
当我们开始注意到问题时,此语句中有 10,000 多个条目v@sql_shared_cursor
。我们设置了一个 cron 作业,每五分钟清除一次游标,但这并不能解决任何问题,只能稍微减轻问题。
再次查看v@sql_shared_cursor
,原来创建许多游标的原因是INST_DRTLD_MISMATCH = Y
。这很奇怪,因为中间件(我们几乎无法直接控制)不会插入那么多行。
我们向供应商询问他们如何进行插入。他们回答说,他们从表中进行选择,WHERE 1 = 0
将列结构放入其内部 ADODB 对象中,然后用相关数据填充该对象。他们通常每“批”执行 1 到 20 次插入。
我猜测,当您进行批量更新时,ADODB 在后台使它看起来像批量插入,这将是 Oracle 将其视为批量操作的唯一合理原因,但我无法找到任何确凿的事实。
有人可以提供见解吗:
- 为什么会发生这种情况?
- 如果与 11g 相关,那么为什么升级两个月后就会发生这种情况?
- 为了彻底解决这个问题,我还应该查看其他哪些参数?
编辑:事实证明这很可能是 Linux 上 Oracle 的一个错误。我们目前正在测试一个补丁,如果事实证明属实,我将在几天内亲自发布答案。
EDIT2:补丁没有修复它 - 虽然我们可能还没有找到原因,但我们可能通过增加重做日志的数量来缓解这个问题。我仍然希望在某个时候写一个答案。
答案1
这原来是 Oracle 的一个错误。在应用下面提到的补丁后,一个月内没有一条语句的游标超过 50 个,问题中描述的性能问题也消失了。
补丁:错误 10636231 - INSERT .. RETURNING 语句的版本计数过高,原因是 INST_DRTLD_MISMATCH
错误 10636231 - INSERT .. RETURNING 语句的版本计数过高,原因是 INST_DRTLD_MISMATCH [ID 10636231.8]
修改日期 2011 年 9 月 17 日 类型 补丁 状态 已发布
错误 10636231 INSERT .. RETURNING 语句的版本计数过高,原因为 INST_DRTLD_MISMATCH 本说明简要概述了错误 10636231。内容最后更新于:2011 年 9 月 17 日 单击此处查看以下每个部分的详细信息。影响:产品(组件)Oracle Server (Rdbms)
被认为受影响的版本范围 版本 >= 11.2.0.2 但低于 12.1
已确认受影响的版本 •11.2.0.2
受影响的平台 通用(所有/大多数平台均受影响)
人们认为这是默认行为的回归,因此:11.2.0.2 中引入了回归
已修复:此问题已在以下版本中修复:•12.1(未来版本)•11.2.0.3 •11.2.0.2.3 补丁集更新 •11.2.0.2 适用于 Exadata 数据库的软件包补丁 8 •11.2.0.1 适用于 Exadata 数据库的软件包补丁 12 •11.2.0.2 适用于 Windows 平台的补丁 7
症状:相关于:•泄漏(内存泄漏/增长)•互斥争用•共享池受到影响•由于 INST_DRTLD_MISMATCH 导致游标未共享•V$SQLAREA•V$SQL_SHARED_CURSOR
描述 该问题是由 11.2.0.2 中对 bug 9380377 的修复引起的
带有 RETURNING 子句的插入 SQL 可能无法共享子游标,从而导致 V$SQLAREA 中的 VERSION_COUNT 较高以及相关问题(可能存在互斥争用等)。如果会话涉及全局事务,则可能会发生这种情况。例如:如果会话正在外部协调事务(如 XA)中执行,或者会话使用数据库链接。
重新发现说明:V$SQLAREA 中的 version_count 较高带有 RETURNING 子句的插入语句涉及全局事务V$SQL_SHARED_CURSOR 中的原因是 INST_DRTLD_MISMATCH