Oracle 查看正在执行的存储过程 sid:用 TaoToken 统一 Key 打通排查链路

发布时间:2026/9/27 16:30:41
Oracle 查看正在执行的存储过程 sid:用 TaoToken 统一 Key 打通排查链路 1. 排查现场谁在跑那个存储过程线上告警响了某个 ETL 存储过程卡住不动业务方催着问「到底哪个会话在跑、能不能杀掉」。你登上 Oracle 数据库第一反应可能是select * from v$session where statusACTIVE结果刷出来几十上百行全是DBMS_SCHEDULER、oraclexxx之类的后台会话根本看不出哪个才是目标存储过程。这就是 DBA 日常最典型的场景知道存储过程名字但不知道它对应的 sid。Oracle 的会话信息分散在多个动态性能视图里v$session只告诉你「谁在活动」v$access告诉你「谁在访问哪个对象」v$open_cursor告诉你「谁打开了含这段 SQL 的游标」dba_ddl_locks则记录 DDL 层面的锁持有情况。单看任何一个视图都不够得把它们串起来才能精准锁定目标会话。这篇就聚焦「Oracle 查看正在执行的存储过程 sid」这个具体问题把查询思路、可复制 SQL、以及用 TaoToken 统一 Key 打通排查链路的配置骨架一次讲清楚。适合谁看需要快速定位阻塞会话的 DBA、做数据平台运维的工程师、以及平时写 PL/SQL 但排查经验不多的开发同学。你不需要装额外工具只要有一个能连数据库的客户端加上一套顺手的 API 通道来辅助分析日志和生成排查脚本就能把整条链路跑通。2. 前置准备TaoToken 统一 Key 与接入骨架排查过程中经常需要把报错日志、执行计划、会话快照丢给模型做分析或者让模型帮你生成一段针对性的查询 SQL。如果每个工具都单独配一套 Key切换起来很烦。TaoToken 的思路是提供一个统一的 API 通道兼容 OpenAI 风格的接口你只需要维护一份 Key就能在命令行工具、IDE 插件、自建脚本里复用。先到官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 注册账号然后在控制台 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 里创建 API Key。拿到 Key 之后接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面有各语言的调用示例。API 基础地址是 https://taotoken.net/api 注意这个地址不带 UTM 参数直接填就行。如果你用的是支持config.toml的命令行工具比如一些 coding agent 或终端助手可以按下面的骨架配置。把YOUR_API_KEY换成你刚创建的那串 Key# config.toml - TaoToken 统一 Key 配置骨架 [provider] name taotoken base_url https://taotoken.net/api api_key YOUR_API_KEY model claude-sonnet-4-20250514 [provider.headers] Content-Type application/json [agent] # 排查场景下建议开启流式输出方便边看边改 SQL stream true timeout_seconds 120 max_retries 2配置好之后你可以用一条最简单的 curl 验证通道是否通curl -s https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer YOUR_API_KEY \ -H Content-Type: application/json \ -d { model: claude-sonnet-4-20250514, messages: [{role: user, content: 用一句话说明 Oracle v$session 的作用}] }返回里能看到choices字段就说明 Key 和通道都正常。这一步别跳过后面排查脚本里如果嵌了模型调用通道不通会浪费很多时间。3. 可复制配置从过程名到 sid 的完整 SQL 链路下面这套 SQL 按「由粗到细」的顺序排列你可以逐条执行也可以把关键几条拼成一个脚本。假设目标存储过程叫P_ETL_CRM_DESK实际用时替换成你的过程名。3.1 第一步确认过程确实在运行先看对象缓存里有没有活跃的锁和 pin。locks 0 and pins 0说明这个过程正在被引用SELECT name, locks, pins FROM v$db_object_cache WHERE locks 0 AND pins 0 AND type PROCEDURE;如果这里能查到P_ETL_CRM_DESK说明过程确实在跑。查不到的话可能是过程已经执行完或者名字大小写不对Oracle 默认存的是大写。3.2 第二步用 v$open_cursor 反查 sid这是最直接的一招。存储过程执行时PL/SQL 引擎会打开游标游标里的 SQL 文本通常包含过程名或调用块SELECT sid, sql_text FROM v$open_cursor WHERE UPPER(sql_text) LIKE %P_ETL_CRM_DESK%;返回结果里SID列就是你要找的会话号。典型输出长这样SID SQL_TEXT 143 begin -- Call the procedure p_etl_crm_desk(v_dtdate :v_dtdate); end;注意sql_text可能被截断如果过程名在很靠后的位置LIKE可能匹配不到。这时候可以放宽条件用过程名的一部分去匹配。3.3 第三步用 v$access 交叉验证v$access记录的是「哪个会话正在访问哪个对象」粒度比游标更粗但胜在稳定SELECT sid, owner, object, type FROM v$access WHERE object P_ETL_CRM_DESK;输出示例SID OWNER OBJECT TYPE 143 KDCC P_ETL_CRM_DESK PROCEDURE如果第二步和第三步查出来的 sid 一致基本可以确认。不一致的话说明可能有多个会话在访问同一个过程需要结合v$session的status和last_call_et进一步判断哪个是真正在执行的。3.4 第四步用 dba_ddl_locks 看锁持有有些场景下过程被 DDL 锁卡住这时候dba_ddl_locks能给出更明确的信号SELECT session_id AS sid, owner, name, type, mode_held AS held, mode_requested AS request FROM dba_ddl_locks WHERE name P_ETL_CRM_DESK;输出示例SID OWNER NAME TYPE HELD REQUEST 143 KDCC P_ETL_CRM_DESK Table/Procedure/Type Null Nonemode_held为Null通常表示只是引用没有强锁如果出现Exclusive之类的值说明有会话在持有排他锁那就要重点看这个 sid。3.5 第五步把 sid 关联到会话详情拿到 sid 之后用v$session补全会话信息方便判断能不能杀、要不要杀SELECT s.sid, s.serial#, s.username, s.program, s.status, s.last_call_et, s.sql_id, s.event, s.blocking_session FROM v$session s WHERE s.sid 143;重点关注statusACTIVE 还是 INACTIVE、last_call_et已执行秒数、event等待事件、blocking_session被谁阻塞。如果blocking_session有值说明这个会话本身也在等别人得顺着链往上找。3.6 第六步结合 dba_source 确认过程定义有时候过程名对不上是因为有重载或者包内过程。用dba_source搜一下定义确认你查的是正确的对象SELECT owner, name, type, line, text FROM dba_source WHERE UPPER(text) LIKE %P_ETL_CRM_DESK% AND owner KDCC ORDER BY owner, name, line;这一步在过程名有歧义时特别有用能帮你确认到底有几个同名对象、分别属于哪个 schema。4. 验证请求跑一遍看结果把上面的 SQL 串起来写一个可复用的排查脚本。下面这个版本用绑定变量避免硬解析也方便你在 SQL*Plus 或 SQL Developer 里直接跑-- 排查脚本根据过程名定位 sid VARIABLE proc_name VARCHAR2(100); EXEC :proc_name : P_ETL_CRM_DESK; -- 1. 对象缓存确认活跃 SELECT name, locks, pins FROM v$db_object_cache WHERE locks 0 AND pins 0 AND type PROCEDURE AND name UPPER(:proc_name); -- 2. 游标反查 sid SELECT sid, sql_text FROM v$open_cursor WHERE UPPER(sql_text) LIKE % || UPPER(:proc_name) || %; -- 3. v$access 交叉验证 SELECT sid, owner, object, type FROM v$access WHERE object UPPER(:proc_name); -- 4. DDL 锁 SELECT session_id AS sid, owner, name, type, mode_held, mode_requested FROM dba_ddl_locks WHERE name UPPER(:proc_name);执行完之后把查到的 sid 填进下面这条看会话详情SELECT sid, serial#, username, program, status, last_call_et, sql_id, event, blocking_session FROM v$session WHERE sid target_sid;实测下来大部分场景第二步就能直接命中。如果第二步没结果第三步和第四步通常能补上。三步都查不到那大概率过程已经执行完或者你查的过程名和实际执行的不一致回到dba_source再确认一遍。如果你想把排查结果丢给模型做进一步分析比如「这个 sid 的等待事件是enq: TX - row lock contention帮我分析可能的原因」可以用 TaoToken 的模型对话通道 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 把会话快照贴进去让模型帮你梳理阻塞链。长期做编码和 Agent 类任务的话Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 会更划算适合需要频繁调用模型的场景。5. 常见错排查查不到 sid 怎么办情况一v$open_cursor查不到但过程确实在跑。最常见的原因是sql_text被截断或者 PL/SQL 块里过程名不是字面量而是拼接的。这时候改用v$access它的对象名是完整的。另外注意v$open_cursor只显示当前打开的游标如果过程在两次 fetch 之间可能暂时看不到。情况二查出来多个 sid。说明有并发执行。用v$session的last_call_et排序值最大的通常是执行最久的那个。也可以看sql_id结合v$sql的executions和elapsed_time判断哪个是主会话。情况三权限不足。v$session、v$access这些视图需要SELECT ANY DICTIONARY或者被授予SELECT_CATALOG_ROLE。如果报ORA-00942: table or view does not exist先找 DBA 要权限。dba_ddl_locks和dba_source同样需要 DBA 权限。情况四过程名大小写问题。Oracle 默认把未加引号的标识符转成大写。如果你建过程时用了双引号比如p_etl_crm_desk那查询时也得用双引号精确匹配。建议统一用大写省去麻烦。情况五RAC 环境下 sid 不唯一。在 RAC 里sid只在实例内唯一跨实例要用inst_id sid组合。查询时加上inst_id列比如SELECT inst_id, sid FROM gv$session WHERE ...。gv$开头的视图是 RAC 全局视图单实例下也能用。情况六TaoToken 通道报 401 或 403。先检查config.toml里的api_key有没有多余空格再确认base_url是不是https://taotoken.net/api不要带路径后缀。如果用的是环境变量确认变量名和配置里引用的一致。接入文档里有各语言的完整示例对照检查一遍基本能解决。6. 把排查链路固化下来上面这套流程跑顺之后建议把它固化成一个脚本或者一个 SQL 片段库。我自己的做法是建一个dba_tools目录里面放几个.sql文件按「过程名排查」「会话阻塞排查」「锁等待排查」分类。每次遇到问题直接改个参数就跑不用重新想 SQL。TaoToken 的 Key 也建议统一管理别在多个工具里散落。config.toml里配一份环境变量里配一份脚本里通过环境变量读取这样换 Key 的时候只改一个地方。API Keys 管理页面在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 可以随时查看和轮换。最后提醒一句杀会话之前一定要确认清楚。ALTER SYSTEM KILL SESSION sid,serial# IMMEDIATE;这条命令执行下去事务会回滚如果过程正在写关键数据回滚可能带来额外影响。先看blocking_session能解阻塞就解阻塞实在不行再考虑杀会话。排查的目的是定位问题不是制造新问题。