2011-09-16 109 views
3

我有一个错误的代码重复问题,我们无法确定哪些版本的软件包/过程正在使用。即我有与同名程序不同的包,我需要确定哪些包实际上没有被调用。Oracle 10g的SQL Server跟踪等效吗?

我试图消除程序/调用它不再是同一个名字的包。我想运行几周的跟踪,结合数据和查询元数据,并找到候选人进一步调查和停用。

我正在寻找SQL Server的使用sp_trace_setevent 42 sp_trace_create相当于跟踪SP:Starting事件 - 这将让我看到被称为所有的存储过程,然后比较,为的存储过程的整个库存请先查看哪些应该先淘汰。我已经使用DBMS_MONITOR.DATABASE_TRACE_ENABLE生成跟踪文件,但我还没有发现任何解释如何使用TKPROF来解析这些文件的任何东西,但性能 - 况且我更在乎正在使用的程序的语句本身,只是。

回答

3

不认为国际劳工组织将有助于(它做的不仅仅是设置模块和行动和地方吗?登录的时间)作为凯德鲁将不得不修改数据库中的每个包和功能。

一种选择是对在数据库跟踪切换,

ALTER SYSTEM SET sql_trace = true SCOPE=MEMORY; 

,并使用脚本命令来获取虽然警告执行的所有包名的唯一列表 - 这将产生大量的输出和非常快速地填充磁盘空间 - 您可能需要创建一个每天运行的程序文件,然后删除trc文件,然后将所有结果组合在一起以确定哪些文件被使用。

此外,您还需要确保跟踪文件大小没有限制,这可能会阻止它记录所有内容,并确保您有足够的磁盘空间,并且您对运行时不感兴趣,也可以将timed_statistics关闭减少日志记录的数量。

alter system set max_dump_file_size=unlimited; 
alter system set timed_statistics=false; 

如果我看着从Oracle跟踪创建的原始跟踪文件,每个应用程序特定的软件包通话过程调用看起来像这样

===================== 
PARSING IN CURSOR #2 len=69 dep=0 uid=102 oct=47 lid=102 tim=1316845390611021 hv=273704950 
ad='b0d4c728' sqlid='01qnrr4850tzq' 
BEGIN REIM_MATCH_SQL.INIT_SUMMARY_MATCH(:1, :2, :3, :4, :5, :6); END; 
END OF STMT 
PARSE #2:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4,plh=0,tim=1316845390611021 

,所以你可以grep的包的列表中调用这样目录(您可能需要调整输出一点取决于操作系统您正在使用的情况下,TKPROF输出不同),福

find . -name "*.trc" -exec grep "BEGIN " {} \; | cut -d" " -f4 | cut -d"(" -f1 | sort -u > ~/called_procedures.txt 

这不工作因为它们可以在SQL语句中调用,但我认为对于过程而言,它应该没问题。这将在您的主目录中生成一个文件,其中包含您启用跟踪后运行的过程调用的唯一列表。

我在包含9818个跟踪文件(总计19GB磁盘空间)的目录上执行了这个操作,并且在运行带有2个内核和12GB内存的Oracle Enterprise Linux 5的测试盒上花费了10分钟 - 这些跟踪文件仅来自重复测试运行一个程序,这样您就可以想象如果生成机器中的所有内容都会生成这些程序将会多快。

然后你可以从sqlplus中得到的数据库中的所有pacakges /程序列表中特定的模式你有兴趣

set heading off 
set trimspool on 
set pagesize 0 
set feedback off 
spool all_procedures.txt 
SELECT DISTINCT p.object_name||'.'||p.procedure_name 
    FROM all_procedures p 
    JOIN all_objects o ON (o.owner = p.owner AND o.object_name = p.object_name AND o.object_type = 
where p.owner='&owner' 
order by 1 
spool off 

终于做两者的差异来获得候选人

名单
diff all_procedures.txt called_procedures.txt 

不要忘记关掉跟踪,当你完成

ALTER SYSTEM SET sql_trace = false SCOPE=MEMORY; 

另外,您需要小心一些程序,这些程序可能只在某些时段(如月末或年终)运行 - 它们可能看起来并未被使用,但您无法确定,除非每个业务流程在监控期间完成。

希望有所帮助。

+0

非常感谢 - 问题的主要部分将在解析中。这些调用没有以任何特殊方式标记为过程调用(它们看起来与记录的每个其他语句非常相似),所以它将确保正则表达式是准确的,然后在做任何该过程之前进行双重检查有问题的话不叫。有问题的应用程序是一个相当轻微使用的Web应用程序,我可以采取措施卸载跟踪文件。 –

+0

在我目前可以访问的跟踪文件中,程序始终以BEGIN开头的行记录,所以“^ BEGIN”(注意空间也一样)应该没问题,尽管您需要更大的跟踪文件的样本量来确保情况总是如此。祝你好运 –

+0

我检查了我迄今为止所取得的成绩,看起来他们确实拥有BEGIN,所以这应该是一个很好的起点。很明显,当一个例程被确定为删除的候选人时,我可以在代码和跟踪中完整搜索其名称,并获得更高的置信度。 –

0

Oracle跟踪功能已从Oracle 10g中删除。相反,应该使用SQL Trace和TKPROF功能。

在语句传递给应用服务器不同的会话就会变得难以跟踪单独过程从开始到结束多层环境。为了解决这个问题,Oracle引入了端到端应用程序跟踪,它允许客户端进程通过客户端标识符而不是典型的会话标识符来标识。每条跟踪信息都链接到以下信息。

  • 客户端标识符 - 指定“真实”最终用户。使用 DBMS_SESSION.SET_IDENTIFIER过程进行设置。
  • 服务 - 指定一组相关的应用程序。使用 创建DBMS_SERVICE.CREATE_SERVICE过程。
  • 模块 - 指定的应用程序的功能性区域或特征。 使用DBMS_APPLICATION_INFO.SET_MODULE过程进行设置。
  • 行动 - 指定当前动作(插入,更新,删除等) 当前模块内。使用 DBMS_APPLICATION_INFO.SET_ACTION过程进行设置。

参考:

http://www.oracle-base.com/articles/10g/PerformanceTuningEnhancements10g.php#tracing_enhancements

+0

我正在寻找与sp_trace_create同等的sp_trace_setevent 42来跟踪SP:开始事件 - 这将允许我查看所有正在调用的存储过程,然后将其与存储过程的整个库存进行比较,以查看哪些存储过程应该首先调查是否过时。我已经使用DBMS_MONITOR.DATABASE_TRACE_ENABLE来生成跟踪文件,但是我还没有找到任何解释如何使用TKPROF来解析这些文件的任何东西,除了性能 - 我甚至不关心这些语句本身,只是正在使用哪些例程。 –

0

您可以通过从架构登录和注销触发器调用DBMS_PROFILER自动执行此。

--Run this script to install the profiler objects for the user 
@...\RDBMS\ADMIN\proftab.sql 


--Create some objects for testing 
create or replace function test1 return varchar2 is 
begin return 'test1'; end; 
/

create or replace function test2 return varchar2 is 
begin return test1(); end; 
/

create or replace package test3 is 
    function test4 return varchar2; 
    function test5 return varchar2; 
end; 
/

create or replace package body test3 is 
    function test4 return varchar2 is begin return test2(); end; 
    function test5 return varchar2 is begin return 'test5'; end; 
end; 
/

--Create the LOGON trigger to start profiling 
create or replace trigger profiler_logon after logon on test_schema.schema 
begin 
    dbms_profiler.start_profiler(run_comment => sysdate); 
end; 
/


--Create the LOGOFF trigger to write the profiling data 
create or replace trigger profiler_logoff before logoff on test_schema.schema 
begin 
    dbms_profiler.stop_profiler(); 
    dbms_profiler.flush_data(); 
end; 
/


--Logon, run this: 
select test3.test4() from dual; 
select test3.test5() from dual; 
--Logoff, logon, run this: 
select test1() from dual; 
--Logoff, logon to see results 



--The data is stored in these tables. 
select * from plsql_profiler_runs; 
select * from plsql_profiler_units; 
select * from plsql_profiler_data; 


--Use a query like this to find the most common objects. 
--But total_occur is both too low and too high: 
-- It records at the object level, test4 and test5 are combined. 
-- It seems to double many counts - maybe an extra call for initializing? 
select unit_type, unit_owner, unit_name, sum(total_occur) total_occur 
from plsql_profiler_units 
join 
(
    --Get max number of times any line number was called. 
    select runid, unit_number, max(total_occur) total_occur 
    from plsql_profiler_data 
    where total_occur > 0 
    group by runid, unit_number 
) profiler_data 
    on plsql_profiler_units.unit_number = profiler_data.unit_number 
    and plsql_profiler_units.runid = profiler_data.runid 
where plsql_profiler_units.unit_type <> 'ANONYMOUS BLOCK' 
group by unit_type, unit_owner, unit_name 
order by total_occur desc, unit_type, unit_owner, unit_name; 


UNIT_TYPE  UNIT_OWNER  UNIT_NAME TOTAL_OCCUR 
---------  ----------  --------- ----------- 
FUNCTION  TEST_SCHEMA  TEST1  4 
FUNCTION  TEST_SCHEMA  TEST2  2 
PACKAGE BODY TEST_SCHEMA  TEST3  2 

但这里有很多的问题:

  1. 性能 - 是否profling增添了不少的开销?我从来没有像以前那样使用过它,我认为它不适合长期生产使用。您可能需要定期删除或截断数据。或者可以修改proftab.sql中的一些表格;例如删除一些索引和外键。 (虽然我没有尝试过,但它可能会让事情变得更糟!)

  2. 无声故障 - 如果某些东西不能被分析,它就不会显示出来。你需要非常小心,它对所有的模式和对象都能正常工作。从参考文献: “Profiler只收集用户具有CREATE权限的单元的数据;不能使用该软件包对已授予EXECUTE ONLY访问权限的单元进行概要分析通常,如果用户可以调试单元,同一个用户可以对它进行配置,但是可以对一个单元进行配置,看它是否被编译为DEBUG。Oracle建议,正在配置的模块应该被编译为DEBUG,因为这提供了关于数据库中单元的附加信息。

  3. 有没有简单的方法来找到包中的哪个函数或过程被使用。要获得这些信息,您需要比较dba_source.line和plsql_profiler_data.line#的行号。不幸的是,这些查询可能非常困难,因为您需要解析PL/SQL。根据代码的干净程度和简单程度,手动检查代码并创建一个包含相关函数和过程开始和结束行号的表格可能会更容易。

  4. 会话问题 - 注销触发器有时会失败吗?如果连接丢失,或者存在严重的数据库错误,我猜想不会有 注销触发器被触发。在这种情况下,分析器信息将不会写入表中。

  5. 您需要为所有用户进行设置,并合并他们的数据。或者可能你可以用同义词替换表到一个普通的表?

  6. 你必须过滤很多垃圾,如匿名块和其他奇怪的条目。

1

正在运行的Oracle数据库会跟踪所有数据库对象的执行计数。它可以通过v $ db_object_cache视图进行访问。

select * from v$db_object_cache 
where type in ('PROCEDURE'); 

你不需要的将根本不在列表中显示(从未加载)或将被列出0执行。

+0

如果用CREATE或REPLACE替换对象,这会重置吗? –

+0

另外,它是否显示内部程序包的执行?我在上个星期做过测试的同一个数据库上运行它,它只报告SYS软件包,没有我知道运行的应用程序拥有的软件包。 –