如何利用Oracle ASH历史采样分析数据库启动性能,追踪启动时挂起原因?

2026-05-03 06:551阅读0评论SEO基础
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计986个文字,预计阅读时间需要4分钟。

如何利用Oracle ASH历史采样分析数据库启动性能,追踪启动时挂起原因?

相关专题:

直接说结论:oracle数据库启动时本身不产生ash数据,dba_hist_active_sess_history 里查不到“启动瞬间”的会话行为;所谓“通过ash分析启动时性能”,实际是分析启动后短时间内发生的挂起或响应迟滞,核心在于确认数据库是否真正在“启动中卡住”,还是已启动完成但被阻塞。


DBA_HIST_ACTIVE_SESS_HISTORY 查不到启动过程,因为ASH从实例启动后才开始采样

  • ASH(Active Session History)依赖于后台进程 MMNL(Manageability Monitor Light),它在数据库 OPEN 状态之后才启动并开始每秒采样
  • 实例处于 MOUNT 或更早阶段(NOMOUNT)时,MMNL 不运行,ASH 表为空;
  • 所以执行类似 SELECT * FROM DBA_HIST_ACTIVE_SESS_HISTORY WHERE SAMPLE_TIME > SYSDATE - 1/24,若返回零行,不说明“没挂起”,而极可能说明:
    • 数据库根本没成功 OPEN(停在 MOUNT 阶段);
    • 或刚 OPEN 就因锁、资源争用等迅速陷入无响应,但采样尚未覆盖关键窗口。

想定位“启动后立即挂起”,必须结合时间窗口 + 事件类型过滤

  • 真正有用的查询不是查“启动时刻”,而是查 OPEN 后前5–10分钟内高密度等待事件

    • 先确认 OPEN 时间:SELECT STARTUP_TIME FROM V$INSTANCE
    • 再查该时间点后 300 秒内的活跃会话聚合:

      SELECT EVENT, SESSION_STATE, COUNT(*) CNT, ROUND(AVG(ROUND((SAMPLE_TIME - LAG(SAMPLE_TIME) OVER (PARTITION BY SESSION_ID, SESSION_SERIAL# ORDER BY SAMPLE_TIME)) * 24 * 60 * 60, 3)), 2) AVG_WAIT_SEC FROM DBA_HIST_ACTIVE_SESS_HISTORY WHERE SAMPLE_TIME BETWEEN (SELECT STARTUP_TIME FROM V$INSTANCE) AND (SELECT STARTUP_TIME + 300/(24*60*60) FROM V$INSTANCE) GROUP BY EVENT, SESSION_STATE ORDER BY CNT DESC;

  • 关键关注字段:

    • EVENT 出现 enq: TX - row lock contentiongc current requestlibrary cache lock —— 表示应用连接一上来就在抢资源;
    • SESSION_STATE = 'WAITING' 占比超 80%,且 EVENT 高度集中,基本可判定是启动后即被阻塞;
    • SESSION_STATE = 'ON CPU' 持续占主导,要怀疑硬解析风暴或初始化 SQL(如物化视图快速刷新、统计信息自动收集触发)。

RAC 环境下特别注意 DRM 和 GCS 资源争用,它们常在启动后几分钟内爆发

  • 单机数据库挂起多由锁、归档满、FRA 满导致;RAC 则大概率和分布式资源管理有关;
  • DRM(Dynamic Resource Management)会在实例 OPEN 后根据首次访问模式自动迁移资源主节点,若此时有批量作业立刻连入,极易触发:
    • gc cr grant 2-waygc current grant 2-way 等等待飙升;
    • LMD 进程 trace 中出现 Rcvd DRM(...) 日志;
  • 验证方式:
    • V$ACTIVE_SESSION_HISTORY(非历史表,实时内存)中是否有大量 gc * 等待;
    • 对比 AWR 报告中 “Global Cache and Enqueue Services” 部分的“Average Active Sessions”曲线是否在启动后陡升;
    • 若确认是 DRM 导致,临时禁用:
      ALTER SYSTEM SET "_gc_affinity_time"=0 SCOPE=SPFILE;(需重启生效)

真正难排查的,不是“ASH里有没有数据”,而是“数据库到底卡在哪一层”:
是 OS 层磁盘 I/O hang 住控制文件读取?是 ASM diskgroup mount 失败但未报错?还是某条 startup trigger 里执行了带锁的 PL/SQL?
这些都不会留下 ASH 记录,必须配合 alert.logOSWatcher 输出、以及 oradebug hanganalyze 3 的即时转储交叉验证。
ASH 只是拼图的一角,别让它成为唯一依据。

标签:Oracle

本文共计986个文字,预计阅读时间需要4分钟。

如何利用Oracle ASH历史采样分析数据库启动性能,追踪启动时挂起原因?

相关专题:

直接说结论:oracle数据库启动时本身不产生ash数据,dba_hist_active_sess_history 里查不到“启动瞬间”的会话行为;所谓“通过ash分析启动时性能”,实际是分析启动后短时间内发生的挂起或响应迟滞,核心在于确认数据库是否真正在“启动中卡住”,还是已启动完成但被阻塞。


DBA_HIST_ACTIVE_SESS_HISTORY 查不到启动过程,因为ASH从实例启动后才开始采样

  • ASH(Active Session History)依赖于后台进程 MMNL(Manageability Monitor Light),它在数据库 OPEN 状态之后才启动并开始每秒采样
  • 实例处于 MOUNT 或更早阶段(NOMOUNT)时,MMNL 不运行,ASH 表为空;
  • 所以执行类似 SELECT * FROM DBA_HIST_ACTIVE_SESS_HISTORY WHERE SAMPLE_TIME > SYSDATE - 1/24,若返回零行,不说明“没挂起”,而极可能说明:
    • 数据库根本没成功 OPEN(停在 MOUNT 阶段);
    • 或刚 OPEN 就因锁、资源争用等迅速陷入无响应,但采样尚未覆盖关键窗口。

想定位“启动后立即挂起”,必须结合时间窗口 + 事件类型过滤

  • 真正有用的查询不是查“启动时刻”,而是查 OPEN 后前5–10分钟内高密度等待事件

    • 先确认 OPEN 时间:SELECT STARTUP_TIME FROM V$INSTANCE
    • 再查该时间点后 300 秒内的活跃会话聚合:

      SELECT EVENT, SESSION_STATE, COUNT(*) CNT, ROUND(AVG(ROUND((SAMPLE_TIME - LAG(SAMPLE_TIME) OVER (PARTITION BY SESSION_ID, SESSION_SERIAL# ORDER BY SAMPLE_TIME)) * 24 * 60 * 60, 3)), 2) AVG_WAIT_SEC FROM DBA_HIST_ACTIVE_SESS_HISTORY WHERE SAMPLE_TIME BETWEEN (SELECT STARTUP_TIME FROM V$INSTANCE) AND (SELECT STARTUP_TIME + 300/(24*60*60) FROM V$INSTANCE) GROUP BY EVENT, SESSION_STATE ORDER BY CNT DESC;

  • 关键关注字段:

    • EVENT 出现 enq: TX - row lock contentiongc current requestlibrary cache lock —— 表示应用连接一上来就在抢资源;
    • SESSION_STATE = 'WAITING' 占比超 80%,且 EVENT 高度集中,基本可判定是启动后即被阻塞;
    • SESSION_STATE = 'ON CPU' 持续占主导,要怀疑硬解析风暴或初始化 SQL(如物化视图快速刷新、统计信息自动收集触发)。

RAC 环境下特别注意 DRM 和 GCS 资源争用,它们常在启动后几分钟内爆发

  • 单机数据库挂起多由锁、归档满、FRA 满导致;RAC 则大概率和分布式资源管理有关;
  • DRM(Dynamic Resource Management)会在实例 OPEN 后根据首次访问模式自动迁移资源主节点,若此时有批量作业立刻连入,极易触发:
    • gc cr grant 2-waygc current grant 2-way 等等待飙升;
    • LMD 进程 trace 中出现 Rcvd DRM(...) 日志;
  • 验证方式:
    • V$ACTIVE_SESSION_HISTORY(非历史表,实时内存)中是否有大量 gc * 等待;
    • 对比 AWR 报告中 “Global Cache and Enqueue Services” 部分的“Average Active Sessions”曲线是否在启动后陡升;
    • 若确认是 DRM 导致,临时禁用:
      ALTER SYSTEM SET "_gc_affinity_time"=0 SCOPE=SPFILE;(需重启生效)

真正难排查的,不是“ASH里有没有数据”,而是“数据库到底卡在哪一层”:
是 OS 层磁盘 I/O hang 住控制文件读取?是 ASM diskgroup mount 失败但未报错?还是某条 startup trigger 里执行了带锁的 PL/SQL?
这些都不会留下 ASH 记录,必须配合 alert.logOSWatcher 输出、以及 oradebug hanganalyze 3 的即时转储交叉验证。
ASH 只是拼图的一角,别让它成为唯一依据。

标签:Oracle