「什么是10046 Trace」?
10046 Trace 是 Oracle 提供的一种事件跟踪机制,它可以捕获 SQL 语句的执行路径和等待事件的详细信息。通过启用这个跟踪,我们可以看到 SQL 执行的每一步细节,包括执行计划、逻辑和物理读取、等待事件等。这些信息对分析和优化数据库性能至关重要。
「何时使用10046 Trace」?
在遇到以下情况时,使用10046 Trace 是非常有帮助的:
某些SQL语句执行时间过长,需要深入了解其执行过程。
系统整体性能下降,但无法通过常规监控手段确定瓶颈。
需要精确分析SQL语句的资源消耗和等待事件。
事件10046是为Oracle会话收集扩展SQL_TRACE信息的标准方法,这需要DBA权限。
对于查询性能问题,通常需要记录查询的等待和绑定变量信息。这可以通过使用级别12的10046事件实现。以下示例说明了如何在各种情况下设置事件:
「trace位置」
「11g R1及以上版本:」
随着Oracle数据库11g第1版引入的新诊断基础设施,跟踪和核心文件被放置在由DIAGNOSTIC_DEST初始化参数控制的位置。 可以使用以下命令显示DIAGNOSTIC_DEST的位置:
SQL> show parameter diagnostic_dest
「11g R1之前:」
事件10046 trace将会在中为用户进程生成trace文件,并在中为后台进程生成trace文件。 可以使用以下命令显示user_dump_dest的位置:
SQL> show parameter user_dump_dest
「注意:」 某些示例包括设置'tracefile_identifier'以帮助找到生成的trace输出。
「会话跟踪」
这种trace可用于在语句开始前用户可以访问会话的情况。 要在会话级别收集10046跟踪:
alter session set tracefile_identifier='10046';
alter session set timed_statistics = true;
alter session set statistics_level=all;
alter session set max_dump_file_size = unlimited;
alter session set events '10046 trace name context forever,level 12';
-- 在此处执行要跟踪的查询或操作 --
select * from tab1;
exit;
如果未退出会话,则可以使用以下命令禁用trace:
alter session set events '10046 trace name context off';
请注意,如果会话未干净关闭且未禁用trace,则重要的跟踪信息可能会从trace文件中丢失。
「注意:」 "statistics_level=all" 设置在此处是为了在参数已从默认和推荐的“典型” (TYPICAL) 级别更改为“基本” (BASIC) 时收集某些级别的统计信息。为了诊断性能问题,需要某些级别的统计信息。虽然“ALL”级别可能不是绝对必要的,但为了诊断,选择了“ALL”级别以获取最全面的信息。
「跟踪已启动的进程」
如果需要从现有会话收集trace信息,可以使用「oradebug」附加到会话并启动10046 trace。
首先要通过某种方式识别要跟踪的会话:
例如,在SQL*Plus中,启动一个会话以查找目标会话的操作系统进程ID (spid):
select p.PID, p.SPID, s.SID
from v$process p, v$session s
where s.paddr = p.addr
and s.sid = &SESSION_ID;
「SPID」 是操作系统进程标识符 (os pid) 「PID」 是Oracle进程标识符 (ora pid)
如果不知道会话ID,可以使用类似以下的选择语句来帮助识别目标会话:
col line for a79
set heading off
select 'ospid: ' || p.spid || ' # ''' ||s.sid||','||s.serial#||''' '||
s.osuser || ' ' ||s.machine ||' '||s.username ||' '||s.program line
from v$session s , v$process p
where p.addr = s.paddr ;
对于12c中的多线程进程,使用v$process中的新添加的列stid查找特定线程,因为Oracle将许多进程组合到一个ospid中。要查找特定线程,使用以下语法:
oradebug setospid <spid> <stid>
确定进程的操作系统进程ID后,可以按如下方式初始化trace:
假设要跟踪的进程的操作系统进程ID为9834。以DBA身份登录到SQL*Plus并执行以下命令:
connect / as sysdba
oradebug setospid 9834
oradebug unlimit
oradebug event 10046 trace name context forever,level 12
请记住将示例'9834'值替换为实际的操作系统进程ID。
「注意:」 也可以使用setorapid通过oradebug附加到会话。
在这种情况下,将使用「PID」 (Oracle进程标识符) 而不是'SPID',并且oradebug文本将更改为:
connect / as sysdba
oradebug set_ora_pid 9834
oradebug unlimit
oradebug event 10046 trace name context forever,level 12
请记住将示例'9834'值替换为实际的Oracle进程ID。
要在完成跟踪后禁用oradebug跟踪:
oradebug event 10046 trace name context off
「文档」 对于12c中的多线程进程,使用v$process中的新添加的列stid查找特定线程,因为Oracle将许多进程组合到一个ospid中。要查找特定线程,使用以下语法:
oradebug setospid <spid> <stid>
oradebug unlimit
-- 跟踪文件名类似于<instance><spid>_<stid>.trc。
「实例范围trace」
「注意:」 设置系统范围时请小心,因为这将影响性能,因为每个会话都会被跟踪。
该设置将在设置参数后跟踪每个新建的会话。现有会话不会被跟踪。
在以下情况下,系统范围的10046跟踪可能很有用:已知问题会话会发生但无法提前识别。在这种情况下,可以在短时间内启用跟踪,然后重现问题,最后禁用跟踪并在生成的跟踪文件中搜索问题证据。
可以按如下方式启用系统范围跟踪:
alter system set events '10046 trace name context forever,level 12';
可以使用以下命令禁用所有会话中的设置:
alter system set events '10046 trace name context off';
「初始化参数设置」
该设置将在重新启动实例时跟踪实例中的每个会话。
event="10046 trace name context forever,level 12"
可以通过删除参数并重新启动实例或使用以下alter system命令禁用该设置:
alter system set events '10046 trace name context off';
「通过登录触发器」
在某些情况下,可能需要跟踪特定用户的活动。在这种情况下,可以使用登录触发器。以下是一个示例:
CREATE OR REPLACE TRIGGER SYS.set_trace
AFTER LOGON ON DATABASE
WHEN (USER like '&USERNAME')
DECLARE
lcommand varchar(200);
BEGIN
EXECUTE IMMEDIATE 'alter session set tracefile_identifier=''From_Trigger''';
EXECUTE IMMEDIATE 'alter session set statistics_level=ALL';
EXECUTE IMMEDIATE 'alter session set max_dump_file_size=UNLIMITED';
EXECUTE IMMEDIATE 'alter session set events ''10046 trace name context forever, level 12''';
END set_trace;
「注意:」 要跟踪会话,执行触发器的用户需要显式授予“alter session”权限。即:
grant alter session to <USERNAME>;
「欢迎关注我们的公众号,获取更多技术分享与经验交流。」




