暂无图片
暂无图片
4
暂无图片
暂无图片
5
暂无图片

SQL解析失败跟踪案例分享(Oracle19c)

原创 Rune_DB 2025-03-19
319

1. 问题现象

分享一个跟踪SQL解析错误的案例。
在日常 Oracle 数据库监控过程中,发现 alert 日志中不定时出现大量解析报错的记录,解析报错意味着没有执行计划也没有实际的执行结果,那么该怎么跟踪问题呢?
(PS:以下具体SQL内容经处理转换)

报错具体内容如下:

WARNING: too many parse errors, count=55718 sql hash=....
PARSE ERROR: ospid=...., error=904 for statement:
Additional information: hd=..., phd=..., flg=..., cisid=..., sid=..., ciuid=..., uid=...
sqlid=***hidden_sqlid*** Current username=XXXXXXXX  
Application: JDBC Thin Client Action

复制

2. 问题定位步骤

2.1 通过 ASH 分析 SQL 活动历史

首先,通过 V$ACTIVE_SESSION_HISTORY (ASH) 表查询 SQL 的活动历史记录,找出与错误 sqlid 相关的会话信息。

执行以下 SQL 语句:

SELECT ASH.SAMPLE_TIME + 0, ASH.SQL_OPNAME, ASH.EVENT, ASH.MACHINE, ASH.MODULE, ASH.PROGRAM, ASH.ACTION FROM V$ACTIVE_SESSION_HISTORY ASH WHERE ASH.SQL_ID = 'hidden_sqlid' ORDER BY ASH.SAMPLE_TIME;
复制

查询结果:

  • machine:显示了具体的服务器来源,如hidden_machine

  • MODULE:均为 JDBC Thin Client

由于 MODULE 显示为 JDBC,结合 machine 信息,进一步推断出该 SQL 来自应用服务器端的调用。


2.2 使用 10046 事件进行 TRACE 跟踪

由于 DBMS_MONITOR 包的限制,它需要 确定会话 ID (SID)MODULEACTION 等字段唯一时才能使用。当前情况中 MODULE 不唯一,SID 也不固定,因此无法使用 DBMS_MONITOR

在这种情况下,直接通过 ALTER SYSTEM SET EVENTS 命令对目标 SQL 的 sqlid 进行跟踪。

启用 TRACE:

ALTER SYSTEM SET EVENTS 'sql_trace [sql:hidden_sqlid] level=12';
复制
  • 注意事项

  • sql:sqlid 之间不能有空格。

  • level=12 之间也不能包含空格。

TRACE 文件路径:

执行以下命令找到生成的 .trc 文件:

cd $ORACLE_BASE/diag/rdbms/$db_name/$instance_name/TRACE ls -lrt | grep hidden_sqlid
复制

关闭 TRACE:

跟踪完成后及时关闭 TRACE,避免产生多余的日志:

ALTER SYSTEM SET EVENTS 'sql_trace [sql:hidden_sqlid] off';
复制

3. 分析 TRACE 文件

通过 TRACE 文件内容,找到解析错误的 SQL 及具体报错信息,示例如下:

PARSE ERROR #140530744166976:len=325 dep=0 uid=hidden_uid oct=3 lid=101 tim=hidden_time err=904
SELECT FIELD1, FIELD2, FIELD3 AS "alias_field", FIELD4
FROM HIDDEN_TABLE_NAME
WHERE FIELD5 = '01' 
  AND FIELD6 = '0' 
  AND FIELD7 = '1' 
  AND ROWNUM <= 10 
ORDER BY FIELD8;

复制

解析结果:

  • 错误代码ORA-00904: invalid identifier

  • 错误原因:表 HIDDEN_TABLE_NAME 中引用了不存在的字段 FIELD7


4. 解决问题与总结

4.1 问题修复

根据 ORA-00904 错误提示,手动检查数据库表结构,发现字段 FIELD7 并不存在。因此,联系开发团队对 SQL 进行修正,确保字段与表结构匹配。

4.2 工具分析总结

针对 SQL 解析失败问题,可以使用以下工具进行排查:

  1. V$ACTIVE_SESSION_HISTORY (ASH)
  • 分析 SQL 活动历史,确定 SQL 来源及相关会话信息。

  • 适用于 SQL 解析失败且无法在 V$SQLDBA_HIST_SQLTEXT 中找到的情况。

  1. ALTER SYSTEM SET EVENTS
  • 在无法通过 DBMS_MONITOR 跟踪时,适合直接对目标 SQL 进行精准跟踪,捕获 trace 文件。

  • 使用语法:ALTER SYSTEM SET EVENTS 'sql_trace [sql:<sqlid>] level=12';

  1. 10046 事件分析
  • 通过 TRACE 文件捕获 SQL 的解析、执行和等待事件,便于分析具体报错原因。
  1. DBMS_MONITOR
  • 适合 SIDMODULE/ACTION 唯一时启用 SQL 跟踪,对性能分析非常有帮助。

5. 最终总结

通过 ASH 分析10046 事件跟踪TRACE 文件解析,成功定位了 SQL 解析失败的根本原因,最终修正了 SQL,解决了问题。其实这个问题归根到底还是因为对发布的SQL代码缺少验证和测试,今后要更严格把关才是。如果是一场SQL错误的解析风暴,那后果不堪设想。


感谢阅读!

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论

阿伟的DBA笔记
暂无图片
3天前
评论
暂无图片 0
ALTER SYSTEM SET EVENTS 'sql_trace [sql:hidden_sqlid] level=12'; 这里是否可以使用alter session呢,生产环境不知道能不能用alter system
3天前
暂无图片 点赞
1
Rune悠然
暂无图片
2天前
回复
暂无图片 0
@阿伟的DBA笔记: session级肯定不行,因为无法直接定位到具体哪个会话,生产上alter system这种自然还是交给DBA或者排查故障的专人
2天前
暂无图片 点赞
回复
淡定
暂无图片
6天前
评论
暂无图片 0
SQL解析失败跟踪案例分享(Oracle19c)
6天前
暂无图片 点赞
评论
广州_老虎刘
暂无图片
9天前
评论
暂无图片 2
可以试试这个方法: alter system set events '10035 cursordump(1)'; ---开启 alter system set events '10035 cursordump(0)'; ---关闭
9天前
暂无图片 2
1
Rune悠然
暂无图片
9天前
回复
暂无图片 0
学到了,设置10035对于这个问题更有针对性,感谢
9天前
暂无图片 点赞
回复