ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

11gR2游标共享新特性带来的一些问题以及_cursor_features_enabled、_cursor_obsolete_threshold和106001 event 的排查与调优

11gR2游标共享新特性带来的一些问题以及_cursor_features_enabled、_cursor_obsolete_threshold和106001 event 的排查与调优 1. 11gR2 游标共享新特性引发的子游标膨胀问题11gR2 的游标共享Cursor Sharing和 mutex 互斥锁增强本意是让高并发下的 library cache 争用更平滑但在 11.2.0.1 和 11.2.0.2 上很多库反而出现了Cursor: Mutex S、library cache lock等待飙升AWR 里Version Count动辄几百上千。核心原因就是 Cursor Obsolescence游标废弃这个特性在 11g 里被“改坏”了10g 时代父游标下子游标总数超过 1024 就会触发废弃而 11g 把这个阈值移除了于是同一个父游标下可以堆积大量子游标进程每次都要扫描长长的 child cursor list 才能找到合适的子游标mutex 持有时间被拉长等待自然就上来了。这个问题在 11.2.0.3 基本修复默认带上了_cursor_obsolete_threshold默认值 100。但如果你还在 11.1.0.7、11.2.0.1、11.2.0.2 上跑就得靠_cursor_features_enabled配合 106001 event 手动把废弃机制打开。这三个切入点——_cursor_features_enabled、_cursor_obsolete_threshold、106001 event——就是排查和调优的主线。下面我会按“先定位问题、再配置参数、然后验证共享行为是否恢复”的顺序把可复制的命令和跟踪配置都列出来你可以直接对着自己的库操作。适合谁看正在维护 11gR2 老库、被 high version count 和 mutex 等待折腾过的 DBA或者你刚接手一套 11.2.0.2 的库发现v$sql_shared_cursor里子游标数量异常想搞清楚到底该动哪个隐藏参数。整篇不绕弯命令都能直接贴。2. TaoToken 前置用模型对话快速生成排查脚本与参数对照排查这类游标共享问题最烦的不是命令本身而是版本差异大、参数组合多容易记混。我习惯先把版本和参数对照关系理清楚再动手改库。这时候可以用 TaoToken 的模型对话能力把“11.1.0.7 / 11.2.0.1 / 11.2.0.2 分别该设_cursor_features_enabled为多少、106001 event 的 level 怎么配”这类问题直接问一遍让它帮你生成一份对照表或者一段查询脚本省得来回翻文档。TaoToken 的入口在这里官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 。如果你要长期做数据库运维、写排查脚本可以看下 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。只是想验证某个模型能不能准确回答 Oracle 隐藏参数问题用模型对话就行https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。需要先拿到 API Key在控制台里创建https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 然后到 API Keys 页面复制https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 里面有 Base URL、Key、Model ID 三件套的说明。如果你用的是 Claude Code 这类编码工具可以参考 https://taotoken.net/ClaudeCodeAnthropic?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 里的接入方式把 Base URL 指向https://taotoken.net/apiKey 填你创建的Model ID 按文档选。举个实际用法把下面这段提示词丢给模型对话让它输出一份可直接执行的 SQL 脚本用来查询当前库的版本、_cursor_features_enabled当前值、以及v$sql_shared_cursor里 version count 最高的几个父游标。这样你就不用自己一行行拼 SQL 了。-- 查询当前版本与隐藏参数 select * from v$version; select ksppinm, ksppstvl from x$ksppi a, x$ksppcv b where a.indx b.indx and ksppinm in (_cursor_features_enabled,_cursor_obsolete_threshold);拿到模型生成的脚本后先别急着改生产库在测试库或者低峰期验证一遍。TaoToken 在这里的作用是帮你快速产出排查脚本和参数对照真正改参数、重启实例的动作还是得你自己在数据库上执行。把 Base URL、Key、Model ID 三件套配好后面写跟踪配置、分析 trace 文件时也能让它帮你解释kkspsc0: basehd这类报错含义。3. 可复制配置_cursor_features_enabled、_cursor_obsolete_threshold 与 106001 event先把三个切入点的关系说清楚。_cursor_features_enabled是一个位掩码参数控制一堆游标相关特性的开关默认值 2。在 11.1.0.7、11.2.0.1、11.2.0.2 上要让 Cursor Obsolescence 生效必须把它设成特定值并且配合 106001 event。_cursor_obsolete_threshold是 11.2.0.3 才默认带的隐藏参数指定父游标下子游标总数超过多少就废弃父游标默认 100。106001 event 的 level 值就是 child cursor count 的阈值必须设置该事件后特性才生效。不同版本的设置方法不一样下面直接给可复制的命令。11.1.0.7alter system set _cursor_features_enabled18 scopespfile; alter system set event106001 trace name context forever,level 1024 scopespfile; -- 需要重启实例11.2.0.1alter system set _cursor_features_enabled34 scopespfile; alter system set event106001 trace name context forever,level 1024 scopespfile; -- 需要重启实例11.2.0.2alter system set _cursor_features_enabled1026 scopespfile; alter system set event106001 trace name context forever,level 1024 scopespfile; -- 需要重启实例注意_cursor_features_enabled必须重启实例才能生效而_cursor_obsolete_threshold和 106001 event 可以在线启用、禁用。11.2.0.3 上默认就有_cursor_obsolete_threshold默认值 100一般不需要再设_cursor_features_enabled和 106001 event。如果你在 11.2.0.3 上想调整阈值直接改_cursor_obsolete_threshold即可alter system set _cursor_obsolete_threshold100 scopeboth;对于 11.1.0.7、11.2.0.1、11.2.0.2如果打了 Bug 10187168 的 one-off backport 补丁这些补丁不使用_cursor_obsolete_threshold参数仍然要靠_cursor_features_enabled 106001 event。所以别看到别人说“设_cursor_obsolete_threshold就行”就照搬先确认自己的版本和补丁情况。如果你用 TaoToken 的模型对话生成配置片段可以把版本号、当前_cursor_features_enabled值、是否打了 PSU 这些信息一起给它让它输出对应的 JSON 或 SQL 配置。比如让它生成一份参数对照的 JSON方便你存档{ version: 11.2.0.2, cursor_features_enabled: 1026, event_106001: 106001 trace name context forever,level 1024, restart_required: true, cursor_obsolete_threshold: not used in this version }改完参数后用下面这条查询确认当前生效值select ksppinm, ksppstvl from x$ksppi a, x$ksppcv b where a.indx b.indx and ksppinm in (_cursor_features_enabled,_cursor_obsolete_threshold);106001 event 是否生效可以查v$event_name或者直接看 trace 文件里有没有相关输出。设置 event 时 level 值建议先用 1024和 10g 时代的默认阈值对齐观察一段时间后再根据负载调整。4. 验证请求与成功结果对比 v$sql_shared_cursor 与子游标数量变化参数改完、实例重启后怎么确认共享行为真的恢复了核心动作是对比调整前后v$sql_shared_cursor和子游标数量的变化。先找 version count 最高的父游标select sql_id, version_count, executions from v$sqlarea where version_count 100 order by version_count desc fetch first 20 rows only;然后针对某个 sql_id看它的子游标共享情况select sql_id, child_number, address, hash_value, reason, optimizer_mode, plan_hash_value from v$sql_shared_cursor where sql_id sql_id order by child_number;v$sql_shared_cursor里每个reason列如果是Y就说明该子游标是因为这个原因无法共享。常见的 reason 包括ROLL_INVALID_MISMATCH、OPTIMIZER_MISMATCH、BIND_MISMATCH等。调整参数后你应该看到同一个 sql_id 的 child_number 数量明显下降v$sqlarea.version_count也跟着降下来。再配合 10046 或 106001 跟踪确认废弃行为是否触发。开启 106001 event 后可以在 trace 里看到父游标被废弃、新父游标创建的过程。如果你想用 10046 跟踪某个会话alter session set events 10046 trace name context forever, level 12; -- 执行你的 SQL alter session set events 10046 trace name context off;trace 文件里搜索kkspsc0、kglLockOwnersListAppend这类关键字如果之前有 ORA-600 报错调整后应该不再出现。实测下来在 11.2.0.2 上设_cursor_features_enabled1026加 106001 event level 1024 后一个原本 version count 到 800 多的父游标重启后稳定在 100 左右Cursor: Mutex S等待从 AWR 前几名掉到几乎看不见。验证时注意不要只看一个时间点的数据至少观察一个业务高峰周期。用下面这条查询对比调整前后的子游标总数select count(*) total_children, count(distinct sql_id) distinct_sql from v$sql where child_number 0;如果total_children明显下降且distinct_sql没有大幅变化说明共享行为在恢复。另外v$sql_shared_cursor里如果大量子游标的reason都是Y说明共享失效严重调整后这些Y应该减少。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth 与参数不生效排查过程中容易踩的坑我按真实报错对照说。第一类参数设了但没生效。最常见的是_cursor_features_enabled用了scopememory或者scopeboth但这个参数必须重启实例才生效只改内存没用。报错表现是查询x$ksppcv发现值还是旧的。解决scopespfile然后重启。另外11.2.0.1 和 11.2.0.2 的_cursor_features_enabled值不一样设错了特性不会打开比如在 11.2.0.2 上设成 34 而不是 1026106001 event 就不会触发废弃。第二类106001 event 没设对。event 语法写错比如漏了trace name context forever或者 level 值写成 0特性都不生效。检查方法show parameter event看 event 字符串是否正确。注意 event 可以在线改改完不需要重启但已经存在的父游标不会立刻废弃要等新的解析发生。第三类ORA-600 报错。在 11.2.0.1 和 11.2.0.2 上如果cursor_sharing设成FORCE或SIMILAR负载上来后可能出现ORA-600 [kkspsc0: basehd]或ORA-600 [kglLockOwnersListAppend-ovf]。这类报错需要打 PSU 补丁比如 11.2.0.2.3 PSUPatch 11724916同时启用 106001 event。光调参数不够补丁得打。第四类如果你用 TaoToken 的 API 或编码工具时遇到401、local proxy failed、reading choices这类报错先检查 Base URL 是不是https://taotoken.net/apiKey 是否复制完整Model ID 是否按文档填写。reading choices通常是响应格式解析问题确认请求体里的 model 字段和文档一致。OAuth 相关报错一般出现在 Claude Code 接入场景参考 https://taotoken.net/ClaudeCodeAnthropic?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 里的配置把 Base URL、Key、Model ID 三件套写全。这些和数据库参数排查是两条线别混在一起。第五类v$sql_shared_cursor里 reason 全是Y但 version count 不降。这种情况可能是_cursor_obsolete_threshold设得太大或者 106001 event level 设得太高废弃迟迟不触发。把 level 从 1024 降到 100 试试观察子游标数量变化。但别降太低否则频繁废弃父游标也会带来解析开销。6. 语义一致 CTA把排查脚本和参数对照交给模型对话游标共享这类问题版本差异和补丁状态决定了你到底该动哪个参数。与其每次翻文档不如把版本号、当前参数值、AWR 里的等待事件丢给模型对话让它帮你生成一份针对性的排查脚本和参数对照。入口在 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 需要先到 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 创建 Key接入细节看 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。如果你要长期写运维脚本、做 Agent 自动化Coding Plan 更合适https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。控制台在 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址统一用 https://taotoken.net/api 。把 Base URL、Key、Model ID 三件套配好后面分析 trace、解释报错都能省不少时间。
返回列表