60-Oracle 10046事件-实操

在实操中,10046功能强大需要多次尝试才算顺手。功能丰富的10046再结合tkprof等格式化工具将原始跟踪数据转化为可读报告,能够极大提升分析效率。对于复杂性能问题,尤其是涉及优化器行为异常、递归SQL效率低下或系统级性能下降的场景,10046事件往往是最终解决方案的关键所在。作为Oracle DBA核心技能之一,深入理解和熟练运用10046事件将显著提升数据库性能优化工作的质量和效率。

一、 配置10046与脚本实践

高效运用10046事件需要掌握其完整的生命周期管理技术,包括事件激活、参数优化、文件定位和结果分析。不同应用场景下需要采用差异化的跟踪策略。

1. 基础配置与跟踪管理

配置10046事件前需设置 核心参数以优化跟踪输出:
时间统计精确性 ​:

  • timed_statistics必须设置为TRUE(默认为TRUE),确保等待事件和CPU时间记录精确到微秒级
    文件大小控制 ​:
  • max_dump_file_size建议设为UNLIMITED,避免大跟踪被截断
    文件标识 ​:
    tracefile_identifier设置会话跟踪文件的自定义后缀,简化文件查找
    统计级别 ​:
    statistics_level=ALL可增强执行计划细节(生产环境谨慎使用)
    跟踪会话脚本
bash 复制代码
-- 会话级跟踪(通用脚本)
ALTER SESSION SET tracefile_identifier = '20250621_trace_10046';
ALTER SESSION SET timed_statistics = true;
ALTER SESSION SET max_dump_file_size = unlimited;
ALTER SESSION SET statistics_level = all; 
-- 可选,增加细节但负载高
ALTER SESSION SET events '10046 trace name context forever, level 12';

-- 执行待分析的SQL或PL/SQL
SELECT e.employee_id,e.FIRST_NAME, d.DEPARTMENT_NAME
FROM HR.EMPLOYEES e JOIN HR.DEPARTMENTS d ON e.DEPARTMENT_ID = d.DEPARTMENT_ID
AND e.job_id='IT_PROG';

-- 关闭跟踪(两种方式任选)
ALTER SESSION SET events '10046 trace name context off';
-- 或直接退出会话
--运行记录
SYS@CDB$ROOT> ALTER SESSION SET tracefile_identifier = '20250621_trace_10046';
Session altered.
SYS@CDB$ROOT> ALTER SESSION SET timed_statistics = true;
Session altered.
SYS@CDB$ROOT> ALTER SESSION SET max_dump_file_size = unlimited;
Session altered.
SYS@CDB$ROOT> ALTER SESSION SET statistics_level = all; 
-- 可选,增加细节但负载高
Session altered.
SYS@CDB$ROOT> ALTER SESSION SET events '10046 trace name context forever, level 12';
Session altered.
SYS@CDB$ROOT> SELECT e.employee_id,e.FIRST_NAME, d.DEPARTMENT_NAME
  2  FROM HR.EMPLOYEES e JOIN HR.DEPARTMENTS d ON e.DEPARTMENT_ID = d.DEPARTMENT_ID
  3* AND e.job_id='IT_PROG';
           103 Alexander     IT
           104 Bruce         IT
           107 Diana         IT
           106 Valli         IT
           105 David         IT
SYS@CDB$ROOT> ALTER SESSION SET events '10046 trace name context off';
Session altered.
SYS@CDB$ROOT>
2. 多会话跟踪技术

实际性能分析中常需跟踪 其他会话或系统级活动,Oracle提供了多种跨会话跟踪技术:
DBMS_SYSTEM程序包 ​:

  • 通过SET_EV过程为指定SID/SERIAL#的会话启用跟踪,这是9i/10g的主要方法。需注意此方法需要SYS权限且语法较复杂。
bash 复制代码
-- 对其他会话启用跟踪(需SYS权限),提前获得sid,serial#
BEGIN 
   DBMS_SYSTEM.SET_EV(
      sid => 1371, 
      serial => 17, 
      ev => 10046, 
      level => 12, 
      name => '');
END;
/

oradebug命令行工具​:通过setospid或setorapid关联到操作系统进程ID后激活事件,适合诊断已存在的会话。

bash 复制代码
-- 使用oradeug跟踪其他进程
SELECT spid FROM v$process WHERE addr = (SELECT paddr FROM v$session 
WHERE sid = &sid);
ORADEBUG setospid <spid>
ORADEBUG event 10046 trace name context forever, level 12

系统级跟踪​:通过ALTER SYSTEM为所有当前和新建会话启用跟踪,此方式影响范围大,生产环境需谨慎。

bash 复制代码
-- 系统级跟踪(影响大,慎用)
ALTER SYSTEM SET events '10046 trace name context forever, level 8';
3. 文件定位与格式化分析

定位跟踪文件是分析的前提,不同版本有差异方法:

  • 11g+简化查询:通过v$diag_info视图直接获取路径
bash 复制代码
-- 11g+文件定位
SELECT value AS trace_file FROM v$diag_info WHERE name = 'Default Trace File';
--/opt/oracle/diag/rdbms/free/FREE/trace/FREE_ora_132316_20250621_trace_10046.trc
SYS@CDB$ROOT> show parameter diagnostic_dest;
NAME            TYPE   VALUE
--------------- ------ -----------
diagnostic_dest string /opt/oracle
SYS@CDB$ROOT> show parameter user_dump_dest ;
NAME           TYPE   VALUE
-------------- ------ ---------------------------------------------
user_dump_dest string /opt/oracle/product/23ai/dbhomeFree/rdbms/log
SYS@CDB$ROOT> show parameter background_dump_dest;
NAME                 TYPE   VALUE
-------------------- ------ ---------------------------------------------
background_dump_dest string /opt/oracle/product/23ai/dbhomeFree/rdbms/log
SYS@CDB$ROOT>

通用版本查询​:通过多表关联获取完整路径

bash 复制代码
-- 通用文件定位(9i/10g/11g)
SELECT p.tracefile 
FROM v$process p, v$session s 
WHERE p.addr = s.paddr 
AND s.sid = (SELECT sid FROM v$mystat WHERE rownum = 1);
--/opt/oracle/diag/rdbms/free/FREE/trace/FREE_ora_132316_20250621_trace_10046.trc

原始跟踪文件(Raw Trace)可读性差,需使用tkprof工具格式化:

tkprof(Trace Kernel Profile)是Oracle数据库自带的性能诊断工具,主要用于格式化原始SQL跟踪文件​(如10046事件或SQL_TRACE生成的.trc文件),生成可读性强的分析报告,帮助DBA识别性能瓶颈

bash 复制代码
--23 ai
tkprof /opt/oracle/diag/rdbms/free/FREE/trace/FREE_ora_132316_20250621_trace_10046.trc output.tkp explain=HR/Oracle_4U sys=no waits=yes aggregate=yes
--19c
tkprof /u01/app/oracle/diag/rdbms/test19/test19/trace/test19_ora_27003.trc output.tkp explain=HR/Oracle_4U sys=no waits=yes aggregate=yes

表:tkprof关键参数解析

|-----------|-----------------------|--------------------|
| ​参数​ | ​功能描述​ | ​推荐值​ |
| explain | 为SQL生成执行计划 | 用户名/密码 |
| sys | 是否包含SYS用户SQL | no(减少干扰) |
| waits | 汇总等待事件信息 | yes |
| aggregate | 合并相同SQL语句 | yes |
| sort | 排序选项(如fchela, prsela) | fchela(按fetch时间排序) |
| table | Explain使用的方案表 | 指定自定义表(可选) |

二、使用场景

1. 跟踪当前会话(Current Session)​​
方法1:ALTER SESSION命令
bash 复制代码
-- 开启跟踪(Level 12 = 绑定变量+等待事件)
ALTER SESSION SET EVENTS '10046 trace name context forever, level 12';

-- 执行目标SQL
SELECT * FROM HR.employees WHERE EMPLOYEE_ID='145';

-- 关闭跟踪
ALTER SESSION SET EVENTS '10046 trace name context off';

-- 查找跟踪文件
SELECT value AS trace_file FROM v$diag_info WHERE name = 'Default Trace File';
TRACE_FILE
_____________________________________________________________
/opt/oracle/diag/rdbms/free/FREE/trace/FREE_ora_145425.trc

方法2:DBMS_SESSION包

bash 复制代码
-- 开启跟踪
EXEC DBMS_SESSION.session_trace_enable(waits=>TRUE, binds=>TRUE);

-- 执行SQL
SELECT * FROM HR.employees WHERE EMPLOYEE_ID='145';

-- 关闭跟踪
EXEC DBMS_SESSION.session_trace_disable();

-- 获取跟踪文件(同上)
2. 跟踪其他会话(Other Session)​​
方法1:DBMS_SYSTEM包
bash 复制代码
-- 查询目标会话信息(SID=182, SERIAL#=9802)
SELECT sid, serial#, username, status 
FROM v$session 
WHERE username = 'SYS';
--
   SID    SERIAL# USERNAME    STATUS
______ __________ ___________ _________
    21      21946 SYS         ACTIVE
    44       6355 SYS         ACTIVE
    54      48562 SYS         ACTIVE
   169      21945 SYS         ACTIVE
   182       9802 SYS         ACTIVE

-- 开启跟踪(Level 12)
EXEC DBMS_SYSTEM.set_ev(182, 9802, 10046, 12, '');

-- 等待目标会话执行SQL(如:HR用户执行查询)

-- 关闭跟踪
EXEC DBMS_SYSTEM.set_ev(182, 9802, 10046, 0, '');

-- 获取跟踪文件
SELECT p.tracefile 
FROM v$session s, v$process p 
WHERE s.paddr = p.addr AND s.sid = 182;
方法2:DBMS_MONITOR包
bash 复制代码
-- 开启跟踪(SID=182, SERIAL#=9802)
EXEC DBMS_MONITOR.session_trace_enable(
  session_id => 182, 
  serial_num => 9802,
  waits      => TRUE,
  binds      => TRUE
);

-- 关闭跟踪
EXEC DBMS_MONITOR.session_trace_disable(182, 9802);
3. 跟踪指定SQL_ID
bash 复制代码
-- 查找SQL_ID(需提前执行目标SQL)
SELECT sql_id, sql_text 
FROM v$sql 
WHERE sql_text LIKE '%employees%';

-- 开启跟踪(SQL_ID='abc123')
ALTER SYSTEM SET EVENTS 
'SQL_TRACE [SQL: abc123] WAIT=TRUE, BIND=TRUE, LEVEL=12';

-- 执行目标SQL(触发跟踪)
SELECT * FROM HR.employees e WHERE e.employee_id = 100;

-- 关闭跟踪
ALTER SYSTEM SET EVENTS 
'SQL_TRACE [SQL: abc123] OFF';

-- 获取跟踪文件
SELECT tracefile FROM v$diag_info;
4. 命令行工具(oradebug)
bash 复制代码
-- 跟踪当前会话
oradebug setmypid
oradebug unlimit
oradebug event 10046 trace name context forever, level 12

-- 执行SQL
SELECT * FROM HR.jobs j WHERE j.job_id = 'IT_PROG';

-- 关闭跟踪
oradebug event 10046 trace name context off

-- 直接输出跟踪文件路径
oradebug tracefile_name
5. 解析跟踪文件(tkprof)​

tkprof(Trace Kernel Profile)是Oracle数据库自带的性能诊断工具,主要用于格式化原始SQL跟踪文件​(如10046事件或SQL_TRACE生成的.trc文件),生成可读性强的分析报告,帮助DBA识别性能瓶颈

bash 复制代码
--转换二进制trc为可读文本
tkprof /opt/oracle/diag/rdbms/free/FREE/trace/FREE_ora_145425.trc
       /tmp/trace_output.txt 
       sys=no 
       aggregate=yes 
       sort=prsela,exeela,fchela
关键参数说明:​
  • sys=no:过滤SYS用户操作
  • sort=prsela:按解析时间排序
  • waits=yes:包含等待事件信息
  • bind=yes:输出绑定变量值
验证结果示例
bash 复制代码
TKPROF输出文件头部:
********************************************************************************
COUNT = SQL执行次数
CPU   = CPU时间(秒)
ELAPSED = 总耗时(秒)
DISK   = 物理读次数
QUERY = 逻辑读次数(一致性读)
CURRENT = 逻辑读次数(当前模式)
ROWS   = 处理行数
bash 复制代码
SQL ID: 8hx54hqvg6tr 
SELECT * FROM HR.employees e WHERE e.department_id = 10
 
Call     Count  CPU   Elapsed  Disk Query  Current  Rows
------- ------ ----- -------- ----- ----- -------- ------
Parse       1  0.00     0.00     0     0        0      0
Execute     1  0.00     0.00     0     0        0      0
Fetch       5  0.01     0.05    10   200        0     45
------- ------ ----- -------- ----- ----- -------- ------
Total       7  0.01     0.05    10   200        0     45

等待事件:
Event waited on           Times  Max Wait  Total Waited
------------------------ ------ --------- -------------
db file sequential read       5      0.02          0.05
注意事项
  • 权限要求

  • 跟踪其他会话需ALTER SYSTEM或DBA权限

  • 使用DBMS_SYSTEM/DBMS_MONITOR包需EXECUTE权限

  • 生产环境建议

    bash 复制代码
    -- 限制跟踪文件大小
    ALTER SESSION SET max_dump_file_size = 1G;
    
    -- 精简跟踪级别(避免Level 12的高负载)
    ALTER SESSION SET EVENTS '10046 trace name context forever, level 4'; 
    • 高级诊断
    • Level 16:添加执行计划中的行源统计信息
bash 复制代码
ALTER SESSION SET EVENTS '10046 trace name context forever, level 16';
--精准捕获SQL执行细节。建议结合AWR/ASH报告交叉分析,优先跟踪高负载SQL(v$sqlstats中ELAPSED_TIME排序)。

三、高级诊断场景

除常规SQL优化外,10046还在特殊场景中发挥关键作用:

  • 并行查询诊断:跟踪文件记录并行从属进程的操作,通过setorapid跟踪特定从属进程
  • RMAN/Data Pump性能:在后台进程启用跟踪分析备份恢复、导入导出性能瓶颈
  • 自适应执行计划:12c+中Level 64跟踪捕获因执行时间突变触发的计划重新生成
  • 云环境诊断:Autonomous Database中通过控制台下载DIAGNOSTIC_DEST内容分析

四、使用体验

Oracle 10046事件作为数据库性能分析领域的基石工具,通过其多层次的跟踪能力,为SQL执行过程提供了无与伦比的可见性。从基础执行统计到绑定变量分析,再到等待事件捕获,10046构建了完整的性能诊断体系。随着Oracle版本的演进,10046事件持续增强其诊断精度和应用场景范围------11g的统一诊断目录和新增级别大幅提高了可用性,而12c及以后版本对自适应优化器和多租户环境的支持则确保了其在现代数据库生态中的持续价值。

相关推荐
ProcessOn官方账号25 分钟前
数据分析对比图表-雷达图全面指南
大数据·人工智能·程序人生·职场和发展·数据分析·学习方法·processon
爬山算法43 分钟前
MySQL(84)如何配置MySQL防火墙?
android·数据库·mysql
拾荒的小海螺1 小时前
MySQL:SQL 慢查询优化的技术指南
数据库·sql·mysql
爬山算法1 小时前
MySQL(83)如何设置密码复杂度策略?
android·数据库·mysql
鹏说大数据1 小时前
MySQL5.7 慢查询SQL语句集合
android·sql·adb
weixin_456904271 小时前
SQLite 数据库操作完整指南
数据库·sqlite
漫步者TZ1 小时前
【StarRocks系列】StarRocks vs Mysql
数据库·starrocks·mysql·分布式数据库
Java初学者小白2 小时前
秋招Day14 - MySQL - SQL优化
java·数据库·sql·mysql
淡酒交魂2 小时前
「Flink」算子主要方法介绍
大数据·数据挖掘·数据分析