ITPub博客

首页 > 数据库 > 国内数据库 > 初识 ASH —— 打开数据库的「月光宝盒」

初识 ASH —— 打开数据库的「月光宝盒」

原创 国内数据库 作者:老纪的技术唠嗑局 时间:2025-09-01 14:17:41 0 删除 编辑

初识 ASH  —— 打开数据库的「月光宝盒」

原创  无济  老纪的技术唠嗑局  2025年09月01日 07:00  浙江
一、从超市监控说起:数据库的“时光回溯术”

想象一下这样的场景: 作为超市经理,当顾客抱怨结账排队太久时,你会怎么做?

  1. 回放监控录像  → 锁定客流高峰时段
  2. 观察收银台状态  → 发现某台扫码枪故障
  3. 追踪特定顾客  → 分析滞留原因

ASH(Active Session History)  正是数据库世界的“智能监控系统”。它像一位不知疲倦的记录员,每秒拍摄一张数据库的工作快照,帮你:

  • 🕒  重现任意时刻的数据库状态
  • 🔍  揪出拖慢系统的 “元凶”
  • 📊  量化每个操作的资源消耗

这个神奇的 “月光宝盒” 藏在 OceanBase 的  v$ob_active_session_history  视图中,等待你的探索。

图片


二、五分钟体验:打开数据库的「月光宝盒 」

我们准备了三个零基础实验,让你快 让你快速感受 AS SH 的魅力:

实验 1:查看此时此刻的数据库

让我们看看数据库最近 10 秒在忙什么:


-- 查看系统中最近 10 秒钟的运行状况


SELECT  sample_time  AS  时间,
        -- 精确到微秒的时间戳
       session_id  AS  会话  ID ,
        -- 唯一标识会话的 ID
        CASE
            WHEN  session_state =  'ON CPU'  THEN '工作中'
            ELSE  '等待中'
        END  AS  状态,
        -- 工作状态:CPU 忙碌或等待资源
        event  AS  等待原因  -- 具体的等待事件(如锁、I/O 等)
FROM  v$ob_active_session_history
WHERE  sample_time >  now () -  10  -- 最近10秒钟
AND  session_type =  "FOREGROUND"
ORDER  BY  sample_time  DESC ;

可能看到的结果 :


+
----------------------------+------------+----------+------------------------+


| 时间                        | 会话ID     | 状态      | 等待原因                |
+ ----------------------------+------------+----------+------------------------+
| 2025-03-11 20:16:15.307564 | 3221931170 | 等待中    | px loop condition wait |
| 2025-03-11 20:16:14.285204 | 3221928286 | 工作中    |                        |
| 2025-03-11 20:16:14.285204 | 3221923503 | 等待中    | wait in request queue  |
| 2025-03-11 20:16:14.285204 | 3221923627 | 等待中    | db file data read      |
| 2025-03-11 20:16:14.285204 | 3221927472 | 等待中    | sync rpc               |
| 2025-03-11 20:16:13.262695 | 3221929034 | 工作中    |                        |
| 2025-03-11 20:16:12.240768 | 3221927472 | 工作中    |                        |
+ ----------------------------+------------+----------+------------------------+

我们发现:

  • 会话 3221931170 在等待 px 执行完成(px loop condition wait)
  • 会话 3221923627 在等待读 IO 完成(db file data read)
  • 会话 3221927472 在 20:16:12 工作中,而到 2 秒后,它在等待 rpc 返回结果(sync rpc)

实验 2:找出最忙碌的 “员工”

找出最近 10 分钟的忙碌的会话:


-- 统计最近 10 分钟最活跃的会话


SELECT
  session_id  AS  会话 ID ,
COUNT (*)  AS  工作秒数
FROM  v$ob_active_session_history
WHERE  sample_time >  now () -  600  -- 最近 10 分钟
       AND  session_type =  'FOREGROUND'
GROUP  BY  session_id
ORDER  BY  工作秒数  DESC  limit  3 ;

典型输出 :


+------------+--------------+


| 会话ID      | 工作秒数      |
+------------+--------------+
| 3221977564 |          283 |
| 3221972645 |          142 |
| 3221916432 |          77  |
+------------+--------------+

我们发现,会话 3221977564 在过去 10 分钟里活跃了 283 秒。如果过去时段只有这三个 session,那么会话 3221977564 产生了数据库 283 / (283 + 142 +77) = 56%

实验 3:穿越到过去

查看过去一段时间最繁忙的 sql。


-- 查询过去时间段中,执行负载最高的 sql_id


SELECT
  SQL_ID,
COUNT (*)  AS  工作秒数
FROM  v$ob_active_session_history 
WHERE  sample_time  BETWEEN
       '2025-03-11 10:32:08'
       AND  '2025-03-11 11:32:07'  -- 可修改时间为实际想观察的时段
GROUP  BY  sql_id
ORDER  BY  工作秒数  DESC limit 3 ;

+
----------------------------------+--------------+


| SQL_ID                           | 工作秒数      |
+ ----------------------------------+--------------+
| 1D0BA376E273B9D622641124D8C59264 |        91265 |
| 19AAD9F2FE3CE0023298AB83F7E75775 |        13608 |
| 7BE7497CCCFE8978AD6B92A938D43929 |        13098 |
+ ----------------------------------+--------------+

三、揭开宝盒的秘密:ASH 实现原理

ASH 就像数据库的自动录像机,每秒都会给所有正在工作的会话(比如执行 SQL 的会话)拍摄状态快照,这些快照都存储在  v$ob_active_session_history  这个系统视图中。

具体的实现原理如下:

图片


1. 选择性记录原则

  • 记录所有数据库中执行的任务 ,并赋予其唯一标识 session_id,包括:
    • 用户客户端连接数据库执行 sql 请求。
    • 内部 rpc 执行
    • 后台线程执行任务,如转储线程、clog 线程、定时器线程等
  • 只记录活跃会话的状态,空闲会话不会被记录 ,包括:
    • 正在执行 SQL 的会话认为是活跃的。如果某会话处于 sleep 状态,没有处理 sql 请求,则视为空闲状态,不会记录。
    • 后台线程如果没有执行任务、或在等待新任务调度,则视为空闲状态,不会记录。
    • 正在等待资源(如锁、磁盘 I/O)的会话,ASH 会标记其 等待事件 (如: db file data read )

2. 时间切片机制

每个  observer  内部,有一个专门的 ASH 线程, 以 1 秒为周期 ,访问数据库内全部活跃会话,并记录其状态,其中:

  • gv$ob_active_session_history 中每行的数据代表一个活跃会话在某时刻的状态
  • 如果某个会话的工作时间非常短(比如不到 1 秒),就像拍照时眨眼的人,可能无法被 ASH 捕捉到。对这种场景,建议重复负载并扩大查询时间范围,这样 ASH 的统计结果才更可靠。

3. 环形缓冲区设计

ASH 快照数据保存在 30MB 的循环缓冲区。存储数据超过 30MB 后,会自动覆盖最旧的数据。我们从 4.2.5.3 版本开始实现了覆盖前 ASH 数据自动归档为 WR 的功能。但在之前版本,仍有可能出现 ASH 历史数据丢失,当我们希望保存最新的 ASH 记录时,可以手动触发 WR 快照:


-- 手动触发 WR 快照


CALL  DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT();

执行该命令后,当前时刻还未持久化到 WR 中的 ASH 快照数据以 10:1 的比例持久化。

四、常见问题(FAQ)

Q1:我运行示例 SQL 后没有返回任何数据,这是为什么?

可能有以下两种原因:

  1. 查询期间数据库确实空闲(无活动会话)
  2. 时间范围设置错误(选择的时间段 ASH 数据已被覆盖)

Q2:ASH 的历史数据被覆盖后怎么办?

OceanBase 会自动将 ASH 数据压缩保存到 WR 历史库中,只需查询  dba_wr_active_session_history  (系统租户查询视图  cdb_wr_active_session_history )视图即可。虽然细节有所精简,但关键信息都保留了下来。

有关 WR 更多信息可以查看  OceanBase 官网文档 —— WR 概述 [1] 。

Q3: 开启 ASH 会影响数据库性能吗?

ASH 在 OceanBase 数据库中是常开的,对数据库性能的影响微乎其微(通常不到 1% 的 CPU 消耗),ASH 会恒定占用每个observer 进程 30MB 内存。

五、下回预告

在第二篇中,我们将化身 "数据库侦探",使用 ASH 四维分析法破解这些谜团:

  • 为什么每天下午系统会变慢?
  • 某个 SQL 突然变慢的真相是什么?
  • 如何快速找到拖累系统的 "罪魁祸首" SQL?

六、参考资料

[1]

OceanBase 官网文档 —— WR 概述:  https://www.oceanbase.com/docs/common-oceanbase-database-cn-10000000033813



    已无更多数据

    最后为大家推荐这个 OceanBase 开源负责人老纪的公众号「老纪的技术唠嗑局」,会持续更新和 # 数据库 、# AI 、# 技术架构 相关的各种技术内容。欢迎感兴趣的朋友们关注!

    「老纪的技术唠嗑局」不仅希望能持续给大家带来有价值的技术分享,也希望能和大家一起为开源社区贡献一份力量。如果你对 OceanBase 开源社区认可,点亮一颗小星星 ✨ 吧!你的每一个Star,都是我们努力的动力。


    来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70047136/viewspace-3094671/ ,如需转载,请注明出处,否则将追究法律责任。

    请登录后发表评论 登录
    全部评论

    注册时间:2025-07-22

    • 博文量
      107
    • 访问量
      100924