1. 项目概述
在数据库运维工作中,系统级挂起(HANG)是最令人头疼的问题之一。当整个数据库系统变得无响应时,传统的诊断方法往往捉襟见肘。这时,ASH(Active Session History)与System State Dump的结合分析就成为了DBA的终极武器。
我曾在一次生产事故中,面对一个完全无响应的Oracle数据库集群。通过结合ASH报告和System State Dump分析,最终定位到一个被所有人忽视的Library Cache Lock争用问题。这种组合诊断方法不仅能快速定位问题根源,还能还原挂起前的完整会话场景。
2. 核心概念解析
2.1 ASH工作机制
ASH是Oracle数据库中的一个环形缓冲区,默认情况下会每秒采样一次所有活动会话的信息,包括:
- 会话ID和序列号
- 正在执行的SQL语句
- 等待事件和等待时间
- 当前执行的程序模块
- 用户和机器信息
关键参数_ash_size控制着缓冲区大小,默认情况下ASH数据会保留约1小时(取决于系统活动程度)。通过视图V$ACTIVE_SESSION_HISTORY可以查询这些数据。
注意:ASH数据存储在SGA中,实例崩溃后会丢失。如果需要长期保存,需要配置AWR自动快照或手动导出。
2.2 System State Dump详解
当系统挂起时,通过oradebug命令生成的System State Dump包含了系统状态的完整快照:
oradebug setmypid oradebug unlimit oradebug dump systemstate 266这个266级别的dump会包含:
- 所有进程的调用栈
- 当前的锁和等待链
- 内存结构和队列状态
- 资源管理器的状态
与ASH的实时采样不同,System State Dump是问题发生时的"尸体解剖",提供了系统挂起瞬间的完整状态。
3. 诊断方法实战
3.1 数据收集流程
当系统挂起时,应按以下顺序收集诊断数据:
优先收集ASH数据:
-- 从内存中提取ASH报告 @?/rdbms/admin/ashrpt.sql生成System State Dump:
oradebug setmypid oradebug unlimit oradebug dump systemstate 266 -- 等待约30秒后再次dump以观察变化 oradebug dump systemstate 266收集HANGANALYZE输出:
oradebug hanganalyze 3收集错误日志:
- alert.log
- trace目录下的最新跟踪文件
- OS级别的日志(如/var/log/messages)
3.2 ASH报告分析要点
在分析ASH报告时,重点关注以下部分:
Top Events:
- 查找异常等待事件(如"library cache lock"、"log file sync"等)
- 检查等待时间的分布情况
Top SQL:
- 识别高负载SQL
- 检查是否有长时间运行的DDL操作
Top Sessions:
- 查找阻塞链的源头会话
- 检查会话状态变化趋势
Activity Over Time:
- 确认问题开始的具体时间点
- 观察等待事件的演变过程
3.3 System State Dump分析技巧
分析System State Dump时,使用以下方法定位问题:
查找阻塞链:
BLOCKED ON [0xNNNNNNNN] [name]分析进程状态:
- 查找大量处于"WAITING"或"PINNED"状态的进程
- 检查进程的调用栈(call stack)
资源争用分析:
- 检查enqueue资源的持有者和等待者
- 查找library cache和row cache的争用
结合多个dump:
- 比较不同时间点的dump,观察变化
- 确认阻塞链是否在扩展
4. 典型案例分析
4.1 Library Cache Lock争用
现象:
- 系统完全无响应
- ASH报告显示大量"library cache lock"等待
- 多个会话阻塞在同一个对象上
分析步骤:
- 在ASH中找到最早出现该等待的会话
- 检查该会话正在执行的SQL
- 在System State Dump中查找持有该锁的进程
- 分析该进程的调用栈和操作
解决方案:
- 终止持有锁的会话(如执行DDL被挂起的会话)
- 设置
_kgl_latch_count增加library cache latch数量 - 避免在高峰期执行DDL操作
4.2 Log File Sync性能问题
现象:
- 事务提交缓慢
- ASH显示大量"log file sync"等待
- System State Dump显示LGWR进程状态异常
分析步骤:
- 检查ASH中"log file sync"等待时间分布
- 确认I/O子系统性能(AWR报告中的I/O部分)
- 检查LGWR进程在System State Dump中的状态
- 验证redo log文件配置
解决方案:
- 优化I/O子系统(使用更快的存储)
- 调整
_use_adaptive_log_file_sync参数 - 考虑使用SSD存储redo log
- 增加redo log组和成员
5. 高级技巧与优化
5.1 ASH采样频率调整
对于高并发系统,默认的1秒采样间隔可能丢失关键信息。可以通过隐含参数调整:
alter system set "_ash_sampling_interval"=500 scope=spfile; -- 500毫秒警告:增加采样频率会显著增加内存使用量,需谨慎调整。
5.2 增强型诊断脚本
以下脚本可以自动收集关键诊断信息:
set serveroutput on size unlimited DECLARE v_dumpfile VARCHAR2(100); BEGIN -- 生成ASH报告 v_dumpfile := DBMS_WORKLOAD_REPOSITORY.ASH_REPORT_TEXT( l_dbid => NULL, l_inst_num => NULL, l_btime => SYSDATE-1/24, l_etime => SYSDATE, l_options => 0); DBMS_OUTPUT.PUT_LINE('ASH Report: '||v_dumpfile); -- 生成System State Dump EXECUTE IMMEDIATE 'alter session set events ''immediate trace name systemstate level 266'''; DBMS_OUTPUT.PUT_LINE('System State Dump generated'); END; /5.3 自动化监控方案
建议配置以下自动化监控:
ASH基线监控:
-- 创建异常等待事件监控 BEGIN DBMS_SERVER_ALERT.SET_THRESHOLD( metrics_id => DBMS_SERVER_ALERT.ELAPSED_TIME_PER_CALL, warning_operator => DBMS_SERVER_ALERT.OPERATOR_GE, warning_value => '100', critical_operator => DBMS_SERVER_ALERT.OPERATOR_GE, critical_value => '500', observation_period => 5, consecutive_occurrences => 3, instance_name => NULL, object_type => DBMS_SERVER_ALERT.OBJECT_TYPE_EVENT, object_name => 'library cache lock'); END; /定期System State采样:
-- 创建每小时采样一次的job BEGIN DBMS_SCHEDULER.CREATE_JOB ( job_name => 'SYSTEM_STATE_SAMPLING', job_type => 'PLSQL_BLOCK', job_action => 'BEGIN EXECUTE IMMEDIATE ''alter system dump systemstate 266''; END;', start_date => SYSTIMESTAMP, repeat_interval => 'FREQ=HOURLY;BYMINUTE=0', enabled => TRUE, comments => 'Hourly system state sampling'); END; /
6. 常见问题排查
6.1 ASH数据不完整
可能原因:
- 实例崩溃后ASH数据丢失
- MMNL进程未运行
- ASH缓冲区大小不足
解决方案:
-- 检查MMNL进程状态 SELECT program FROM v$session WHERE program LIKE '%MMNL%'; -- 调整ASH缓冲区大小 alter system set "_ash_size"=20971520 scope=spfile;6.2 System State Dump分析困难
挑战:
- 输出文件庞大(可能超过1GB)
- 信息过于底层难以理解
应对策略:
使用grep过滤关键信息:
grep -A 20 -B 20 "BLOCKED ON" systemstate.dmp使用Oracle提供的分析工具:
orachk -analyze_dump systemstate.dmp关注重复出现的模式和等待链
6.3 高负载下的诊断技巧
当系统负载极高时:
优先收集最小必要数据:
- ASH报告(内存中的)
- 单个System State Dump
- 关键视图的快照(v$session_wait, v$lock等)
使用轻量级命令:
-- 快速会话状态检查 SELECT sid, serial#, status, event, seconds_in_wait FROM v$session WHERE status = 'ACTIVE';避免加重系统负担:
- 不要连续生成多个dump
- 限制收集的数据量
- 优先在测试环境重现问题
7. 工具与资源推荐
7.1 官方工具
Oracle Diagnostic Pack:
- 包含ASH和AWR的图形化分析工具
- 提供时间序列分析和比较功能
SQLT (SQLTXPLAIN):
- 专门的SQL诊断工具
- 可以结合ASH数据进行分析
ORACHK:
- 系统健康检查工具
- 可以自动分析System State Dump
7.2 第三方工具
Tanel Poder的脚本集:
- ash_wait_chains.sql - 可视化ASH中的等待链
- dump_analyzer.sql - System State Dump分析工具
Method R Workbench:
- 专业的性能分析工具
- 支持ASH数据的深度挖掘
Pyora:
- Python开发的Oracle诊断工具
- 可以自动化分析ASH报告
7.3 学习资源
Oracle官方文档:
- Database Performance Tuning Guide
- Database Reference(V$视图说明)
实用书籍:
- 《Oracle Performance Troubleshooting》
- 《Expert Oracle Database Architecture》
技术博客:
- Tanel Poder的博客
- Oracle Scratchpad(Jonathan Lewis)
在实际工作中,我发现将ASH的时间序列分析与System State Dump的瞬时状态快照结合,能够像"时间机器"一样还原问题发生的全过程。这种组合诊断方法已经帮助我解决了数十次严重的系统挂起问题。关键是要养成定期收集基线数据的习惯,这样在问题发生时才有足够的参照物进行比较分析。