ash中区分rman与业务会话应依赖program+module+action组合:program含'rman@'或'oracle@...(tns v1-v3)',module为'backup full'等,而非不可靠的service_name。
ash 中怎么区分 rman 会话和业务会话?
关键不是靠 service_name 字段本身,而是靠 program + module + action 的组合。oracle 不会在 ash 里把 rman 备份会话的 service_name 固定设为某个值(比如 rman),它继承的是连接时使用的 tns 服务名——可能和应用共用同一个 service,也可能被 dba 改成 rman_svc,但不可靠。
真正稳定可过滤的字段是:
-
PROGRAM含rman@或oracle@... (TNS V1-V3)(注意空格和括号) -
MODULE通常是backup full、backup incremental、restore datafile等 -
ACTION可能为空,但有时带通道编号如channel ORA_DISK_1
只依赖 SERVICE_NAME 过滤 RMAN 会话,大概率漏掉或误伤——尤其在用了 FROM SERVICE 的场景下,RMAN 会以备库 service 名连主库,此时 SERVICE_NAME 显示的是备库的服务名,和备份动作完全无关。
为什么 WHERE SERVICE_NAME = 'xxx' 在 ASH 查询里经常失效?
因为 SERVICE_NAME 是客户端连接时声明的,而 RMAN 默认不显式指定。它走的是 Oracle 内部连接协议,SERVICE_NAME 值往往来自 tnsnames.ora 条目或 EZCONNECT 字符串,一旦 DBA 没统一配置,不同 RMAN 脚本连出来的 SERVICE_NAME 就五花八门。
更麻烦的是:RMAN 使用 FROM SERVICE 执行跨库操作时,源端(比如备库)发起的连接,其 SERVICE_NAME 是目标端(主库)的 service 名;但这个连接在 ASH 里仍属于“RMAN 备份会话”,只是它的 SERVICE_NAME 和你预期的“RMAN 专用 service”对不上。
所以直接写 WHERE SERVICE_NAME = 'RMAN_SVC',很可能查不到任何记录——不是没发生备份,而是 service 名根本没设或设错了。
如何写出真正有效的 ASH 过滤 SQL?
优先用 PROGRAM 和 MODULE 定位 RMAN 会话,再按需关联业务影响。例如查过去一小时内 RMAN 是否阻塞了业务读写:
SELECT sample_time, event, p1text, p1, p2text, p2, program, module, sql_id
FROM v$active_session_history
WHERE (program LIKE '%rman%' OR module LIKE 'backup%' OR module LIKE 'restore%')
AND sample_time > SYSDATE - 1/24
AND event IN ('db file sequential read', 'db file scattered read', 'direct path read', 'enq: BF - contention')
ORDER BY sample_time DESC;
如果真要结合 service 分析(比如确认某业务 service 下是否有 RMAN 混入),应改成:
- 先查出所有疑似 RMAN 的
SID和SESSION_ID - 再用这些 SID 去
v$session查对应SERVICE_NAME,而不是反向用 service 去筛 ASH - 因为
v$session的SERVICE_NAME是实时且权威的,而 ASH 是采样快照,字段完整性不保证
FROM SERVICE 场景下 SERVICE_NAME 的真实含义
当执行 RESTORE DATAFILE ... FROM SERVICE standby_db 时,主库上的 RMAN 进程在 ASH 中的 SERVICE_NAME 显示的是 standby_db ——但这不代表它是“备库的会话”,它仍是主库上发起的 RMAN 控制进程,只是通过网络调用备库服务来拉取数据。
此时若你按 SERVICE_NAME = 'standby_db' 去查 ASH,会捞出两类完全不同的会话:
- 真正的备库 RMAN 后台进程(module = 'backup full')
- 主库上那个发请求的 RMAN 控制进程(module = 'restore datafile',但 service_name = 'standby_db')
二者 I/O 行为、等待事件、资源消耗完全不同。混在一起分析,反而掩盖瓶颈位置。最稳妥的做法,始终以 MODULE 为主键,SERVICE_NAME 仅作辅助标签,不参与核心过滤逻辑。











