3

我正在尝试跟踪针对特定数据库用户执行的 SQL 语句。我没有启用审计,我使用的是 Oracle 11g。

我有以下查询:

SELECT  
  S.MODULE, 
  SQL_TEXT , 
  S.EXECUTIONS    
FROM
  SYS.V_$SQL S, 
  SYS.ALL_USERS U
WHERE
  S.PARSING_USER_ID=U.USER_ID 
  AND UPPER(U.USERNAME) IN ('USERNAME')
  AND (UPPER(s.MODULE)='APP.EXE')
ORDER BY S.LAST_LOAD_TIME

但是,如果运行“APP.EXE”的多个用户连接到同一个数据库用户,我无法理解哪个操作系统用户执行了哪个查询。所以我尝试加入 V$SESSION 视图以获取用户详细信息。

SELECT  
  S.MODULE,SQL_TEXT ,SN.OSUSER, SN.MACHINE, S.EXECUTIONS
FROM
  SYS.V_$SQL S, 
  SYS.ALL_USERS U,
  V$SESSION SN 
WHERE
  S.PARSING_USER_ID=U.USER_ID 
  AND UPPER(U.USERNAME) IN ('USERNAME')
  AND (UPPER(S.MODULE)='APP.EXE')
  AND S.SQL_ID=SN.SQL_ID
ORDER BY S.LAST_LOAD_TIME

但这似乎不起作用(在我的情况下它没有返回任何行)所以,我有以下问题

1)如何让每个会话执行的查询?

2) V_$SQL 的 EXECUTIONS 列似乎是所有会话的执行。我如何知道会话执行特定查询的次数?

3) 关于查询的记录将在 V_$SQL 中存储多长时间?Oracle 什么时候从视图中删除它?

先谢谢大家了

普拉迪普

4

3 回答 3

6

如果不进行更多配置(例如启用审计)或做出一些妥协,您可能无法获得您正在寻找的数据。您要解决的业务问题是什么?根据问题,我们可以帮助您确定配置数据库以记录您所需要的信息的最简单方法。

Oracle 不会尝试在任何地方存储特定用户执行特定查询的次数(特别是特定操作系统用户执行特定查询的次数)。SQL_IDinV$SESSION仅表示SQL_ID会话当前正在执行。如果,正如我猜测的那样,这是一个客户端-服务器应用程序,很可能 99% 的时间都是 NULL,因为绝大多数时间,会话没有执行任何 SQL,它正在等待用户做某事。PREV_SQL_IDin是之前执行的V$SESSIONSQL 语句——至少通常不会是NULL. 但它只会有一个值,不会有该会话执行的 SQL 语句的历史记录。

V$SQL视图表示 SQL 共享池中的内容。当 SQL 语句超出共享池时,它将不再出现在V$SQL视图中。发生的速度取决于多种因素——某人执行语句的频率、解析新语句的频率(这通常在很大程度上取决于您的应用程序是否正确使用绑定变量)、您的共享池有多大等. 通常,这将在几分钟到数据库关闭之间。

如果您获得了使用 AWR 表的许可,并且您对近似值而不是完全正确的答案感兴趣,则可以通过查看一些 AWR 表来获得所需的信息。例如,V$ACTIVE_SESSION_HISTORY将捕获每个会话每秒都在积极执行的 SQL 语句。然而,由于这是一个客户端-服务器应用程序,这意味着绝大多数时间会话将处于非活动状态,因此不会捕获任何内容。但是,碰巧为会话捕获的 SQL 语句将让您了解不同 SQL 语句的相对频率。当然,运行时间较长的 SQL 语句也更有可能被捕获,因为它们更有可能在给定时刻处于活动状态。如果查询 A 和 B 都在完全相同的时间内执行,并且在最后一个小时内捕获了一个会话执行 A 5 次和 B 10 次,您可以得出结论 B 的执行频率大约是 A 的两倍。如果您知道查询的平均执行时间,捕获查询的平均概率将是查询执行的秒数(在 0.5 秒内执行的查询有 50% 的机会被捕获,在 0.25 秒内执行的查询有 25% 的机会获得捕获),因此您可以估计特定会话执行特定查询的频率。这远非一个确切的数字,尤其是在较短的时间范围内以及对于实际执行时间变化较大的查询。

视图中的数据V$ACTIVE_SESSION_HISTORY通常可用几个小时。然后将其抽样到DBA_HIST_ACTIVE_SESS_HISTORY表格中,该表格将可用数据量减少了一个数量级,从而使任何估计的准确性大大降低。但是无论您的 AWR 保留时间间隔是多少,该数据都会保留(默认情况下是一周,尽管许多站点将其增加到 30 或 60 天)。

于 2012-07-10T15:01:47.660 回答
1

根据甲骨文文档

SQL_ADDRESS -Used with SQL_HASH_VALUE to identify the SQL statement that is currently being  executed 

SQL_HASH_VALUE - Used with SQL_ADDRESS to identify the SQL statement that is currently being executed 

请找到以下链接以供参考

SQL_ADDRESS 和哈希值

请修改下面的SQL

    SELECT S.MODULE, SQL_TEXT, SN.OSUSER, SN.MACHINE, S.EXECUTIONS
      FROM SYS.V_$SQL S, SYS.ALL_USERS U, V$SESSION SN
     WHERE S.PARSING_USER_ID = U.USER_ID
       AND UPPER(U.USERNAME) IN ('USERNAME')
       AND (UPPER(S.MODULE) = 'APP.EXE')
       AND SN.sql_hash_value = S.hash_value
       AND SN.sql_address = S.address
     ORDER BY S.LAST_LOAD_TIME
于 2012-07-10T15:09:02.133 回答
0

尝试这个

SELECT l.Sql_Id
FROM v$session s
JOIN v$session_longops l 
    ON l.sid = s.Sid 
    AND l.Serial# = s.Serial# 
    AND l.Start_Time >= s.Logon_Time
WHERE s.Audsid = Sys_Context('USERENV', 'SESSIONID')

我假设您只对运行 sql 的日志感兴趣?

于 2014-08-12T15:45:34.567 回答