【问题标题】:tracing all SQL queries which have executed when application fire an order跟踪应用程序触发订单时执行的所有 SQL 查询
【发布时间】:2015-10-12 06:25:29
【问题描述】:

当通过应用程序处理任何订单时,我需要收集应用程序已使用的所有 SQL 查询(SELECT、UPDATE、DELETE、INSERT)。

如果我可以获取通过应用程序处理的至少 50 个订单的所有 SQL,那么我可以在找到这些信息后检查哪些 SELECT、UPDATE、DELETE 语句经常使用,以及应用程序经常使用哪些表。

我可以得出结论,我可以在哪个表上使​​用分区,就好像我使用 WHERE 子句获取整个 SQL 一样,我还可以知道哪种类型的分区对于任何特定的表和分区会更好。

然而,这似乎是一个忙碌的练习,因为应用程序可能使用很多 SQL,但它有助于我理解应用程序,而且在这个练习之后,我将获得一份关于我的应用程序行为与数据库的审查报告,这可以是供后来的员工使用。

为此,到目前为止,我使用了 DBMS_adivsor 包,它为我的数据库的一些表进行了分区,当我检查我在 DBMS_ADVISOR 中使用的 SQL 的解释计划时,我突然想到那些表已满EXPLAIN PLAN 中的表扫描 DBMS_ADVISOR 告诉我对它们进行分区。

问题是我不能根据这些信息对表进行分区,因为它是应用程序级别的分区,而且我的经理也不会被这些小信息说服。所以我想出了上面的计划:(

我需要这样做来找出我可以执行表分区和其他性能调整的表,比如创建索引,因为我可以使用过滤器获得 where 子句,所以它就像一个数据库调整,我想这样做将帮助我发展我在数据库开发方面的职业生涯。

请帮我解决这个问题。

这个查询会给我所需的信息吗?

select st.command 
  from V$SQLTEXT_WITH_NEWLINES st, SYS.V_$SQL s 
 where st.hash_value = s.hash_value
   and parsing_schema_name = 'NETSERVICOS2CM'
   and s.module = 'JDBC THIN CLIENT';

跟踪非 dba 用户的----

GRANT SELECT ON SYS.V_$SESSION TO USER;

GRANT SELECT ON SYS.V_$MYSTAT TO USER;

获取 SID 和 SERAIL#

SELECT sid, serial# FROM SYS.V_$SESSION

WHERE SID = (SELECT DISTINCT SID FROM SYS.V_$MYSTAT);

然后在 DBA 用户上执行这个 --

EXEC DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION (sid=>3002,    serial#=>31833,sql_trace=> true);

在我使用的 no-dba 用户上 --

ALTER SESSION SET SQL_TRACE = TRUE;

EXEC DBMS_SESSION.set_sql_trace(sql_trace => TRUE);

触发跟踪特定用户的会话----

CREATE OR REPLACE TRIGGER ON_MY_SCHEMA_LOGIN
AFTER LOGON ON DATABASE
WHEN ( USER = 'NETSERVICOS1CM' )
BEGIN
  EXECUTE IMMEDIATE 'ALTER SESSION SET TRACEFILE_IDENTIFIER = "net1cm"';
  EXECUTE IMMEDIATE 'alter session set statistics_level=ALL';
  EXECUTE IMMEDIATE 'alter session set events ''10046 trace name context     forever, level 12''';
 EXCEPTION
   WHEN OTHERS THEN
   NULL;
 END; 

之后停止跟踪我正在使用

 ALTER SESSION SET EVENTS '10046 trace name context off';

 ALTER SYSTEM SET EVENTS '10046 trace name context off';

按照 Derek 的建议。

在此之后,您可能有多个跟踪文件来制作一个合并的跟踪文件,我们可以使用 TRCSESS 实用程序 --

trcsess output=net1cm_trcsess.trc module="JDBC Thin Client" *net1cm.trc

它将为在我的案例中生成的所有跟踪文件创建一个单独的跟踪文件 net1cm_trcsess.trc(跟踪文件标识符为 net1cm)。

现在我们可以使用 TKPROF 实用程序来生成人类可读的报告,例如使用以下命令 ---

tkprof net1cm_trcsess.trc OUTPUT=net1cm_trcsess.txt EXPLAIN=netservicos1cm/netservicos1 SYS=NO

谢谢

【问题讨论】:

  • 你可以使用 SQL Profiler

标签: oracle database-performance database-administration database-partitioning


【解决方案1】:

所以这是我的建议。

您可以对应用程序上下文操作使用多种不同的跟踪,例如 INSERT、DELETE、UPDATE、SELECT 甚至所有操作。

假设您有一个由应用程序运行的 PL/SQL 程序,或者有一个对数据库的 OCI 调用。您将在模块/存储过程级别拥有此 Oracle 代码:

dbms_application_info.set_module(<module_name>,'execute');

在执行整个代码之前。 (在代码中的 BEGIN 之后)。

dbms_application_info.set_module(<module_name>,'UPDATE');

在执行更新 SQL 语句之前。

要关闭应用程序上下文,您可以使用(在 END; 之前):

dbms_application_info.set_module(NULL,NULL);

然后,当您执行模块或运行要在模块中跟踪的更新语句时,您将确保在模块运行之前和之后执行此操作

execute DBMS_MONITOR.SERV_MOD_ACT_TRACE_ENABLE( -
service_name => '<service_name>', -
module_name => '<module_name>', -
action_name => DBMS_MONITOR.ALL_ACTIONS, -
waits => TRUE, -
binds => TRUE);

所有操作都将被跟踪,您将确切知道语句在哪里运行以及执行了什么操作。

要关闭它:

execute DBMS_MONITOR.SERV_MOD_ACT_TRACE_DISABLE( -
service_name => '<service_name>', -
module_name => '<module_name>', -
action_name => DBMS_MONITOR.ALL_ACTIONS);

要在会话级别执行此操作,例如,当序列号为 9 且 Sid 为 100 时,您将执行以下操作。 (检查语法)。

execute DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION(9,190,TRUE);

要关闭它:

execute DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION(9,190,FALSE);

在数据库级别,(您必须非常小心,因为它会为整个数据库生成跟踪,并且会填满您的 oracle 数据库上的诊断目录。免责声明:谨慎使用)。

execute DBMS_MONITOR.DATABASE_TRACE_ENABLE(waits=>TRUE, binds=>TRUE, instance_name=>'<Instance_name>');
execute DBMS_MONITOR.DATABASE_TRACE_DISABLE(instance_name=>'<instance_name>');

【讨论】:

  • 感谢 Derek 的回复,但我有一个问题,如果没有 dbms_application_info.set_module(,'execute');设置在我们的 PLSQL 程序中!我需要把它们放在我们的每个程序、函数和包中吗?如果只调用纯 SQL,如 SELECT、UPDATE、DELETE 等。
  • @Derek-- 我正在使用执行 DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION (sid=>3002, serial#=>31833,sql_trace=> true);参加会话,但我是从 DBA 用户执行此操作,但是当我尝试在 NON_DBA 用户上使用它时,当我省略此 PAKCHGE 并 USE ALTER SESSION SET SQL_TRACE =TRUE 授予 ALETR SESSION 权限后,它会给我 DBMS_SYSTEM 包错误给用户,然后它 dis 但是我无法找到文件跟踪文件的名称,而我可以对 DBA 用户执行此操作,请提供任何建议。
  • 您可以在存储过程的开头和结尾使用 dbms_application_info.set 模块,它将在数据库 v$sql 和 v$sqlarea 表中上下文(存储应用程序会话信息)。如果在每个存储过程中设置它是太多的工作。您可以使用 DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION。
  • 跟踪需要 DBA 权限才能运行。但是,如果您有诸如 OEM_MONITOR 之类的角色并且在您的数据库上安装了诊断包,您可以使用对象 DBA_HIST_SQLSTAT 和 DBA_HIST_SNAPSHOT 表对象从 Automatic Workload Repository 收集历史信息。您仍然需要使用 dbms_applicon_info 来获取应用程序上下文,但您不必使用跟踪来在 DBA_HIST* 表中收集此信息。
  • 正如我上面提到的,在没有跟踪的情况下(这几乎需要 DBA),您可以查看 v$sql、v$sqlarea(共享池查询)或 DBA_HIST_SQLSTAT 和DBA_HIST_SNAPSHOT 表(历史)来获取在数据库上运行的所有查询。如果不在存储过程中设置 dbms_application_info,您将不知道它们来自哪些模块。无论如何,如果您需要这些表格中的示例,请告诉我。我会发布另一个解决方案。问候
【解决方案2】:

您可以利用v$sqltext_with_newlines ,V$SESSION and v$session_longops。你可以用这些词谷歌一下,看看这些词是否对你的要求有用。

【讨论】:

  • 这个查询在这里有用吗!请查看已编辑的问题
猜你喜欢
  • 2013-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-27
  • 1970-01-01
  • 1970-01-01
  • 2020-12-14
相关资源
最近更新 更多