你想要的跟踪文件通常都是因为设置了
SQL_TRACE=TRUE生成的结果,或者是通过10046事件使用扩展的跟踪工具生成的,如下所示:

1. 文件位置
不论是使用
SQL_TRACE还是扩展的跟踪工具,Oracle都会在数据库服务器主机的以下两个位置生成一个跟踪文件:
q 如果使用专用服务器连接,会在
USER_DUMP_DEST参数指定的目录中生成跟踪文件。
q
如果使用共享服务器连接,则在
BACKGROUND_DUMP_DEST
参数指定的目录中生成跟踪文件。
要想知道跟踪文件放在哪里,可以从SQL*Plus执行
SHOW PARAMETER DUMP_DEST命令来查看,也可以直接查询
V$PARAMETER视图:


这里显示了3个转储(跟踪)目标。后台转储(background dump)目标由所有“服务器”进程使用(第5章会全面介绍Oracle后台进程及其作用)。
如果使用
Oracle
的共享服务器连接,就会使用一个后台进程;因此,跟踪文件的位置由
BACKGROUND_DUMP_DEST
确定。如果使用的是专用服务器连接,则会使用一个用户或前台进程与
Oracle
交互;所以跟踪文件会放在
USER_DUMP_DEST
参数指定的目录中。如果出现严重的
Oracle
内部错误(如
UNIX
上的“
segmentation fault
”错误),或者如果
Oracle Support
要求你生成一个跟踪文件来得到额外的调试信息,
CORE_DUMP_DEST
参数则定义了此时这个“内核”文件应该放在哪里。一般而言,我们只对后台和用户转储目标感兴趣。需要说明,除非特别指出,这本书里都使用专用服务器连接。
如果你无法访问
V$PARAMETER
视图,那么可以使用
DBMS_UTILITY
来访问大多数(但不是全部)参数的值。从下面的例子可以看出,要看到这个信息(还不止这些),只需要
CREATE SESSION
权限:


2. 命名约定
Oracle
中跟踪文件的命名约定总在变化,不过,如果把你的系统上的跟踪文件名作为示例,应该能很容易地看出这些命名有一个模板。例如,在我的各台服务器上,跟踪文件名如表
3-1
所示。
表
3-1
跟踪文件名示例
跟踪文件名
|
平
台
|
数据库版本
|
ora10g
_ora_24574.trc
|
Linux
|
10g
Release 1
|
ora9ir2
_ora_24628.trc
|
Linux
|
9i Release 2
|
ora_10583.trc
|
Linux
|
9i Release 1
|
ora9ir2w
_ora_688.trc
|
Windows
|
9i Release 2
|
ora10g
_ora_1256.trc
|
Windows
|
10g
Release 1
|
在我的服务器上,跟踪文件名可以分为以下几部分:
q 文件名的第一部分是
ORACLE_SID(但Oracle9
i Release 1例外,在这一版本中,Oracle决定去掉这一部分)。
q 文件名的下一部分只有一个
ora。
q 跟踪文件名中的数字是专用服务器的进程ID, 可以从
V$PROCESS视图得到。
因此,在实际中(假设使用专用服务器模式),需要访问4个视图:
q
V$PARAMETER:找到
USER_DUMP_DEST指定的跟踪文件位置。
q
V$PROCESS:查找进程ID。
q
V$SESSION:正确地标识其他视图中的会话信息。
q
V$INSTANCE:得到
ORACLE_SID
。
前面提到过,可以使用
DBMS_UTILITY
来找到位置,而且通常你“知道”
ORACLE_SID
,所以从理论上讲只需要访问
V$SESSION
和
V$PROCESS
,但是,为了便于使用,这
4
个视图你可能都想访问。
以下查询可以生成跟踪文件名:

显然,在Windows平台上要把
/ 换成
/。如果使用9
i Release 1,只需发出以下查询,不用在跟踪文件名中增加实例名:

3. 对跟踪文件加标记
有一种办法可以对跟踪文件“加标记”,这样即使你无权访问
V$PROCESS和
V$SESSION,也能找到跟踪文件。假设你能读取
USER_DUMP_DEST目录,就可以使用会话参数
TRACEFILE_IDENTIFIER。采用这种方法,可以为跟踪文件名增加一个可以惟一标识的串,例如:

可以看到,跟踪文件还是采用标准的
<ORACLE_SID>_ora_<PROCESS_ID>格式命名,但是这里还有我们为它指定的一个惟一的串,这样就能很容易地找到“我们的”跟踪文件名。
3.2.2 针对内部错误生成的跟踪文件
这一节最后我再来谈谈另一类跟踪文件,这些跟踪文件不是我们想要的,只是由于ORA-00600或另外某个内部错误而自动生成。对这些跟踪文件我们能做些什么吗?
答案很简单,一般来讲,这些跟踪文件不是给你我用的。它们只对Oracle Support有用。不过,我们向Oracle Support提交iTAR时,这些跟踪文件会很有用。有一点很重要:如果得到内部错误,修改这个错误的惟一办法就是提交一个iTAR。如果你只是将错误忽略,除非出现意外,否则它们不会自行修正。
例如,在
Oracle 10gRelease 1
中,如果创建下表,并运行以下查询,就会得到一个内部错误(也可能不会得到错误,因为这个错误已经作为一个
bug
提交,并在后来的补丁版本中得到修正):


如果你是一名DBA,会发现用户转储目标中突然冒出这个跟踪文件。 或者,如果你是一名开发人员,你的应用将产生一个ORA-00600错误,你肯定想知道到底发生了什么。跟踪文件中信息很多(实际上,另外还有35 000行),但一般来讲,这些信息对你我来说都没有用。我们只是想压缩这个跟踪文件,并将其上传来完成iTAR处理。
不过,确实有些信息能帮助你跟踪到“谁”造成了错误,错误是“什么”,以及错误在“哪里”,另外,利用
http://metalink.oracle.com,你还能发现这些问题是不是别人已经遇到过(许多次),以及为什么会出现这些错误。快速检查一下跟踪文件的最前面,你会得到一些有用的信息,如:


你在
http://metalink.oracle.com上提交iTAR时,数据库信息当然很重要,不仅如此,如果在
http://metalink.oracle.com上查看是否以前已经提出过这个问题,这些数据库信息也很有用。另外,可以看出错误出现在哪个Oracle实例上。并发地运行多个实例是很常见的,所以把问题隔离到一个实例上会很有用。

跟踪文件中的这一部分是Oracle 10
g新增的,Oracle9
i里没有。它显示了
V$SESSION的
ACTION和
MODULE列中的会话信息。这里可以看到,是一个SQL*Plus会话导致了错误(开发人员应该设置
ACTION和
MODULE信息;有些环境已经为你做了这项工作,如Oracle Forms和HTML DB)。
另外还可以得到
SERVICE NAME。这就是连接数据库所用的服务名(这里就是
SYS$USERS),由此看出没有通过TNS服务来连接。如果使用
user/pass@ora10g.localdomain登录,可以看到:

其中
ora10g是服务名(而不是TNS连接串;这是所连接TNS监听器中注册的最终服务)。这对于跟踪哪个进程/模块受此错误影响很有用。
最后,在查看具体的错误之前,可以看到会话ID和相关的日期/时间等进一步的标识信息(所有版本都提供了这些信息):

现在可以深入到内部看看错误本身了:


这里也有一些重要的信息。首先,可以看到产生内部错误时正在执行的SQL语句,这有助于跟踪哪个(哪些)应用会受到影响。同时,由于这里能看到SQL,所以可以研究采用哪些“迂回路线”,用不同的方法编写SQL,看看能不能很快绕过问题解决bug。另外,也可以把出问题的SQL剪切并粘贴到SQL*Plus中,看看能不能为Oracle Support提供一个可再生的测试用例(当然,这些是最棒的测试用例)。
另一个重要信息是错误码(通常是600、3113或7445)以及与错误码相关的其他参数。使用这些信息,再加上一些栈跟踪信息(显示按顺序调用的一组Oracle内部子例程),可能会发现这个bug已经报告过(还能找到解决方法、补丁等)。例如,使用以下查询串:

利用
MetaLink
的高级搜索(全文搜索
bug
数据库),很快就能发现
bug 3800614,
“
ORA-600 [12410] ON SIMPLE QUERY WITH ANALYTIC FUNCTION
”。如果访问
http://metalink.oracle.com
,并使用这个文本进行搜索,可以找到这个
bug
,了解到下一版中已经修正了这个
bug
,并注意到已经有相应的补丁,所有这些信息我们都能得到。很多次我都发现,所遇到的错误以前已经出现过,而且事实上已经有了修正和解决的办法。
3.2.3 跟踪文件小结
现在你知道有两种一般的跟踪文件,它们分别放在什么位置,以及如何找到这些跟踪文件。希望你使用跟踪文件主要是为了调整和改善应用的性能,而不只是提交 iTAR。最后再说一句,Oracle Support确实会利用文档中没有记录的一些“事件”,如果数据库遭遇错误,可以利用这些事件得到大量的诊断信息。例如,如果得到一个ORA-01555,但你自认为不该有这个错误,此时Oracle Support就会教你设置这种诊断事件,每次遇到错误时都会创建一个跟踪文件,由此可以帮助你准确地跟踪到为什么会产生错误。