请求Oracle端在ORA-01000错误发生时转储打开游标至表
解决ORA-01000错误时自动转储游标详情到表的Oracle端方案
可以通过Oracle系统触发器结合系统视图实现,全程在数据库端操作,无需应用介入。以下是具体步骤:
1. 创建存储游标详情的表
在应用所属的非管理员schema下创建表,用于存储错误发生时的游标信息:
CREATE TABLE OPEN_CURSORS_DUMP ( DUMP_TIMESTAMP TIMESTAMP DEFAULT SYSTIMESTAMP, SID NUMBER, SERIAL# NUMBER, USERNAME VARCHAR2(30), SQL_ID VARCHAR2(13), SQL_TEXT CLOB, OPEN_CURSORS_COUNT NUMBER, MAX_OPEN_CURSORS NUMBER );
2. 创建捕获ORA-01000的系统触发器
由DBA在数据库端创建触发器,当ORA-01000错误触发时,自动收集当前会话的游标信息并插入上述表:
CREATE OR REPLACE TRIGGER CAPTURE_ORA_01000 AFTER SERVERERROR ON DATABASE DECLARE v_sid NUMBER; v_serial NUMBER; v_username VARCHAR2(30); v_open_cursors NUMBER; v_max_cursors NUMBER; BEGIN -- 仅捕获ORA-01000错误,且限制在周末触发(匹配你的场景) IF (SERVERERROR(1) = 1000) AND (TO_CHAR(SYSTIMESTAMP, 'DY', 'NLS_DATE_LANGUAGE=ENGLISH') IN ('SAT', 'SUN')) THEN -- 获取触发错误的会话信息 SELECT SID, SERIAL#, USERNAME INTO v_sid, v_serial, v_username FROM V$SESSION WHERE AUDIT_SESSIONID = USERENV('SESSIONID'); -- 获取当前会话的打开游标数和系统最大允许值 SELECT VALUE INTO v_open_cursors FROM V$SESSTAT s JOIN V$STATNAME n ON s.STATISTIC# = n.STATISTIC# WHERE s.SID = v_sid AND n.NAME = 'opened cursors current'; SELECT VALUE INTO v_max_cursors FROM V$PARAMETER WHERE NAME = 'open_cursors'; -- 插入会话基本统计信息 INSERT INTO YOUR_APP_SCHEMA.OPEN_CURSORS_DUMP ( SID, SERIAL#, USERNAME, OPEN_CURSORS_COUNT, MAX_OPEN_CURSORS ) VALUES ( v_sid, v_serial, v_username, v_open_cursors, v_max_cursors ); -- 插入该会话所有打开游标的SQL详情 INSERT INTO YOUR_APP_SCHEMA.OPEN_CURSORS_DUMP ( SID, SERIAL#, USERNAME, SQL_ID, SQL_TEXT ) SELECT s.SID, s.SERIAL#, s.USERNAME, c.SQL_ID, t.SQL_TEXT FROM V$OPEN_CURSOR c JOIN V$SESSION s ON c.SID = s.SID AND c.SERIAL# = s.SERIAL# LEFT JOIN V$SQL t ON c.SQL_ID = t.SQL_ID WHERE s.SID = v_sid AND s.SERIAL# = v_serial; COMMIT; END IF; EXCEPTION WHEN OTHERS THEN -- 避免触发器异常导致会话中断,仅记录错误信息 DBMS_OUTPUT.PUT_LINE('Trigger CAPTURE_ORA_01000 error: ' || SQLERRM); END; /
3. 必要的权限配置
- 替换SQL中的
YOUR_APP_SCHEMA为实际应用使用的schema名称 - DBA需给触发器所有者(通常是SYS)授予对目标表的插入权限:
GRANT INSERT ON YOUR_APP_SCHEMA.OPEN_CURSORS_DUMP TO SYS; - 确保触发器所有者拥有访问
V$SESSION、V$SESSTAT、V$STATNAME、V$OPEN_CURSOR、V$SQL这些系统视图的权限(SYS默认具备)
后续分析
ORA-01000错误发生后,应用可直接查询OPEN_CURSORS_DUMP表:
- 通过
OPEN_CURSORS_COUNT和MAX_OPEN_CURSORS确认是否确实超出阈值 - 查看
SQL_TEXT列,定位哪些SQL被频繁打开却未关闭,排查游标泄漏问题
内容的提问来源于stack exchange,提问作者Loïc Gammaitoni
相关产品推荐
相关产品推荐

