一、跟踪文件是干什么用的?
跟踪文件中包含了大量而详细的诊断和调试信息。通过对跟踪文件的解读和分析,我们可以定位问题、分析问题和解决问题。从跟踪文件的产生的来源来看,跟踪文件又可以分为两类:一类是数据库的操作人员有意生成的;另一类则是由于出现了异常错误,由数据库自动生成的。对于后一类,只对Oracle内部的技术支持人员是有用的,但对于我们,则多半看不懂。前一类,则是我们经常用到的,帮助我们分析、调整和优化应用性能,处理并解决问题。
二、跟踪文件是如何命名的?
一个跟踪文件的名字一般由以下几部分组成:
ORACLE_SID
固定字符"ora"
服务器的进程ID号
文件后缀名 .trc
前三个部分之间以下划线连接。
如下例:
orcl_ora_6210.trc
其中“orcl" 是本环境下数据库的SID,"6210"为产生该跟踪文件会话所使用的服务器进程ID号。如何知道我的ORACLE_SID和会话所使用的服务器进程ID呢?后面会详细讲到。
上面说到的跟踪文件的命名规则适用于我们前面说的第一类跟踪文件,即数据库操作人员有意生成的跟踪文件。如果是第二类跟踪文件,则命名上稍有变化。这类跟踪文件将固定字符"ora"改为了ORACLE后台进程名的缩写。如下例所示:
orcl_lgwr_30019.trc
orcl_dbw0_2664.trc
三、跟踪文件存放在哪里?
跟踪文件存放的位置根据数据库版本的不同,位置也是不同的。下面以10g 和11g分别说明。
10g
通常,我们在安装数据库时,会设定一个环境变量$ORACLE_BASE(注意,是BASE,不是HOME),该变量中指定了ORACLE软件安装的主目录。假设我们设定的目录为”/oracle/app/oracle“,那么跟踪文件会放到以下这几个目录中:
/oracle/app/oracle/admin/orcl/bdump 该目录用来存储ORACLE后台进程生成的输出文件。数据库自动生成的跟踪文件默认是存储在这里,另外,我们经常提到的报警日志,也是放在这里的。
/oracle/app/oracle/admin/orcl/cdump 该目录用来存储内核进程产生的输出文件
/oracle/app/oracle/admin/orcl/udump 该目录用来存储用户生成的输出文件。我们有意生成的跟踪文件默认就是存储在这里。
以上是说的是默认情况下,如果数据库的管理员改变了这个设置的话,我们更保险的方法是查询相关参数来确定,查询方法如下:
通过SQLPLUS以管理员身份登录,输入 show parameter dump_dest 并回车。例如:
SQL> show parameter dump_dest
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
background_dump_dest string /oracle/app/oracle/admin/orcl/ bdump
core_dump_dest string /oracle/app/oracle/admin/orcl/cdump
user_dump_dest string /oracle/app/oracle/admin/orcl/ udump
此外,这些设置,在参数文件中也有记录。通过查询参数文件亦可获得。
11g
11g中引入了一个新的功能,称为自动诊断知识库(Automatic Diagnostic Repository 缩写为ADR)。它是所有诊断信息的的中心存储点,它包括各种转储文件、跟踪文件、日志和健康状况监视报表。所有实例(RDBMS实例和ASM实例)都在ADR中创建有自己的目录结构。
ADR的位置是由参数DIAGNOSTIC_DEST来指定,默认位置同$ORACLE_BASE。其结构如下:
ORACLE_BASE/diag/database_name/instance_name
假设我们设定的$ORACLE_BASE仍为”/oracle/app/oracle“,数据库名称和实例名称均为”orcl",则实际的目录结构如下:
/oracle/app/oracle/diag/orcl/orcl
这个位置,也被称为本例中数据库实例ORCL的ADR_HOME。
在这个目录下,还会发现有一个子目录,名为trace,其下集中存储了数据库后台进程和用户主动生成的跟踪文件以及报警日志。
但这也是默认情况下,我们通过查询v$diag_info视图,就可以获得实际的位置。如下所示:
SELECT * FROM V$DIAG_INFO;
INST_ID NAME VALUE
------- --------------------- -------------------------------------------------------------
1 Diag Enabled TRUE
1 ADR Base /u01/oracle
1 ADR Home /u01/oracle/diag/rdbms/orclbi/orclbi
1 Diag Trace /u01/oracle/diag/rdbms/orclbi/orclbi/trace
1 Diag Alert /u01/oracle/diag/rdbms/orclbi/orclbi/alert
1 Diag Incident /u01/oracle/diag/rdbms/orclbi/orclbi/incident
1 Diag Cdump /u01/oracle/diag/rdbms/orclbi/orclbi/cdump
1 Health Monitor /u01/oracle/diag/rdbms/orclbi/orclbi/hm
四、如何找到特定的跟踪文件?
通过上面的介绍,我们已经知道了跟踪文件是如何命名的,存储到了什么地方。但对于一个繁忙的系统,在同一个目录下,可能会在相近的时间内生成多个跟踪文件,那么如何才能找到我们想要的那个跟踪文件呢。核心就是要确定我们所使用的服务器进程ID号。有了这个ID号,我们就可以确定地知道哪个跟踪文件才是我们想要的。下面介绍一下如何查询服务器进程ID号。
当前正在运行的服务器进程ID号,都存储在v$process视图中。但由于该视图中提供的信息有限,大多数的时候,我们很难定位到底哪个服务器进程ID(SPID)才是我们要找的。 比如下面的这个输出,基本是一样的。
SQL> select addr,spid,username,terminal,program from v$process;
ADDR SPID USERNAME TERMINAL PROGRAM
----------------------- ------------ --------------- ------------------------------ ------------------------------------------------
000000007FE6D7A8 2447 oracle UNKNOWN oracle@localhost.localdomain (MMNL)
000000007FE6DFA0 2449 oracle UNKNOWN oracle@localhost.localdomain (D000)
000000007FE6E798 2451 oracle UNKNOWN oracle@localhost.localdomain (S000)
000000007FE6EF90 2453 oracle pts/1 oracle@localhost.localdomain (TNS V1-V3)
000000007FE6F788 2455 oracle UNKNOWN oracle@localhost.localdomain (ARC0)
000000007FE6FF80 2457 oracle UNKNOWN oracle@localhost.localdomain (ARC1)
000000007FE70778 2459 oracle UNKNOWN oracle@localhost.localdomain (CTWR)
000000007FE70F70 2461 oracle UNKNOWN oracle@localhost.localdomain (QMNC)
000000007FE71768 5703 oracle pts/2 oracle@localhost.localdomain (TNS V1-V3)
000000007FE71F60 5839 oracle UNKNOWN oracle@localhost.localdomain
000000007FE73F40 2475 oracle UNKNOWN oracle@localhost.localdomain (q000)
这时,我们就借助v$session视图,即通过会话找服务器进程(一个进程可以有多个会话,但一个会话,只能属于一个进程)。前面说过,跟踪文件分为两类,我们需要的是我们主动生成的跟踪文件。即然是我们主动生成的,那一定是在我们当前的会话中产生。因此,我们可以利用以下语句找到我们当前会话所属的服务器进程ID(SPID)。
SQL> select a.spid from v$process a,v$session b where b.sid=sys_context('userenv','sid') and a.addr=b.paddr;
SPID
------------
5922
上面语句中的 sys_context('userenv','sid') 是利用系统内置的函数来取当前的会话ID(SID),这个函数也可以用 userenv('sid') 来代替,结果是一样的。只不过ORACLE建议使用前者。因为后面这个函数只是出于保持版本的兼容性而保留下来的,但说不定什么时候,这个函数就会在更新的版本中取消了。
有了这个SPID,我们就可以去相应的跟踪文件的存放位置,去查找在当前时间产生的,文件名中含有”5922“的跟踪文件了。
另外,我们也可以使用下面这个SQL语句,在当前会话中直接查询而获得跟踪文件的绝对路径和名字。
select c.value || '/' || d.instance_name || '_ora_' || a.spid || '.trc' trace
from v$process a, v$session b, v$parameter c, v$instance d
where a.ADDR = b.PADDR
and b.SID = sys_context('userenv','sid')
and c.NAME = 'user_dump_dest' ;