Oracle 11g中插入数据的SQL未在v$sql中记录的排查问题
问题描述
我正在查找一个向特定表插入数据的Spring定时任务,但无法确定该Spring应用所在的WAS服务器。因此尝试通过运行的SQL语句追踪该应用,计划将这些语句与v$session表关联以获取机器名等信息,执行的查询语句如下:
SELECT v.SQL_TEXT, v.PARSING_SCHEMA_NAME, v.LAST_LOAD_TIME, v.DISK_READS, v.ROWS_PROCESSED, v.ELAPSED_TIME, v.service, v.MODULE FROM v$sql v WHERE to_date(v.FIRST_LOAD_TIME, 'YYYY-MM-DD hh24:mi:ss')>ADD_MONTHS(trunc(sysdate, 'MM'),-2) AND LOWER(SQL_TEXT) LIKE '%[the_table_name]%' AND LOWER(SQL_TEXT) LIKE '%insert %' ORDER BY FIRST_LOAD_TIME DESC
该定时任务每分钟运行一次,但始终无法找到向目标表插入数据的SQL语句。请问是我的查询存在问题,还是存在插入数据但不记录到v$sql表的情况?
可能的原因及解决方法
一、查询语句本身的问题
FIRST_LOAD_TIME格式错误:v$sql.FIRST_LOAD_TIME的实际格式是YYYY-MM-DD/HH24:MI:SS(斜杠分隔日期和时间),你用空格分隔的格式串转换会导致转换失败,直接过滤掉所有数据。修正后的条件应为:TO_DATE(v.FIRST_LOAD_TIME, 'YYYY-MM-DD/HH24:MI:SS') > ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -2)- 模糊匹配的局限性:
- 如果应用使用绑定变量,
SQL_TEXT中不会显示实际表名(只会出现:1这类占位符),此时LIKE '%[the_table_name]%'无法匹配。可以改用关联v$sql_plan查找涉及目标表的语句,或使用SQL_FULLTEXT(需对应权限):SELECT DISTINCT v.SQL_TEXT, v.PARSING_SCHEMA_NAME, v.LAST_LOAD_TIME FROM v$sql v JOIN v$sql_plan p ON v.SQL_ID = p.SQL_ID WHERE TO_DATE(v.FIRST_LOAD_TIME, 'YYYY-MM-DD/HH24:MI:SS') > ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -2) AND p.OBJECT_NAME = '[THE_TABLE_NAME]' -- Oracle字典表名存为大写,需对应 AND v.COMMAND_TYPE = 2 -- 2是INSERT命令的类型码,精准匹配 ORDER BY v.FIRST_LOAD_TIME DESC LOWER(SQL_TEXT) LIKE '%insert %'可能漏掉带注释(如INSERT /*+ APPEND */)或连写的情况,用COMMAND_TYPE = 2替代模糊匹配更可靠。
- 如果应用使用绑定变量,
- 权限不足:若当前用户没有
SELECT_CATALOG_ROLE权限,v$sql只能展示当前用户执行的SQL,无法看到其他会话的语句。
二、SQL未被记录到v$sql的情况
- 共享池老化淘汰:若系统SQL量极大,共享池空间不足,这条高频执行的简单INSERT语句可能被快速挤出共享池。可查看
v$shared_pool_reserved的等待事件,或临时增大共享池测试。 - 会话级跟踪关闭:如果应用会话执行了
ALTER SESSION SET SQL_TRACE = FALSE,或使用了旧版本的RULE优化器模式,可能导致SQL不存入共享池,不过这种场景现在极少出现。 - 批量插入的特殊处理:比如Spring的
batchUpdate使用OCI批量绑定,SQL文本可能不会完整存入v$sql,此时可查看v$sqlarea获取聚合的SQL信息。
三、替代追踪方案
如果上述方法无效,可尝试:
- 实时监控活跃会话:每分钟查询
v$session,定位执行目标表INSERT的会话:SELECT s.machine, s.program, s.osuser, v.SQL_TEXT FROM v$session s JOIN v$sql v ON s.sql_id = v.sql_id WHERE v.COMMAND_TYPE = 2 AND EXISTS (SELECT 1 FROM v$sql_plan p WHERE p.sql_id = v.sql_id AND p.object_name = '[THE_TABLE_NAME]') - 启用审计:创建审计策略追踪目标表的INSERT操作,从审计日志获取会话信息:
之后从AUDIT INSERT ON [schema].[the_table_name] BY ACCESS;dba_audit_trail中查询记录,里面包含会话的machine、program等关键信息。
内容的提问来源于stack exchange,提问作者정상준
相关产品推荐
相关产品推荐

