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) 或 MODULE
和 ACTION
等字段唯一时才能使用。当前情况中 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 解析失败问题,可以使用以下工具进行排查:
- V$ACTIVE_SESSION_HISTORY (ASH)
-
分析 SQL 活动历史,确定 SQL 来源及相关会话信息。
-
适用于 SQL 解析失败且无法在
V$SQL
或DBA_HIST_SQLTEXT
中找到的情况。
- ALTER SYSTEM SET EVENTS
-
在无法通过
DBMS_MONITOR
跟踪时,适合直接对目标 SQL 进行精准跟踪,捕获trace
文件。 -
使用语法:
ALTER SYSTEM SET EVENTS 'sql_trace [sql:<sqlid>] level=12';
- 10046 事件分析
- 通过
TRACE
文件捕获 SQL 的解析、执行和等待事件,便于分析具体报错原因。
- DBMS_MONITOR
- 适合
SID
或MODULE/ACTION
唯一时启用 SQL 跟踪,对性能分析非常有帮助。
5. 最终总结
通过 ASH 分析、10046 事件跟踪 和 TRACE 文件解析,成功定位了 SQL 解析失败的根本原因,最终修正了 SQL,解决了问题。其实这个问题归根到底还是因为对发布的SQL代码缺少验证和测试,今后要更严格把关才是。如果是一场SQL错误的解析风暴,那后果不堪设想。
感谢阅读!
评论


