module为空或undefined说明应用未显式设置,需检查jdbc setclientinfo、dbms_application_info.set_module等调用;若为'jdbc thin client'则完全未设,应优先补全;module带随机后缀时建议改用client_identifier归因,并在rac+多租户环境下确保inst_id与pdb_name上下文对齐。

查不到 MODULE 字段值?先确认应用是否真的设置了它
ASH 里 MODULE 为空或 UNDEFINED,99% 不是数据库配置问题,而是应用端根本没传。Oracle 不会自动填充这个字段——它只忠实记录客户端通过 DBMS_APPLICATION_INFO.SET_MODULE 或 JDBC setClientInfo("ApplicationName", ...) 显式设置的值。
快速验证:在疑似会话中执行 SELECT SYS_CONTEXT('USERENV', 'MODULE') FROM DUAL。返回空,就别在数据库侧折腾权限或视图了,得回应用代码或连接池配置里补。
- JDBC 必须显式调用
connection.setClientInfo("ApplicationName", "order-service"),仅配 URL 参数无效 - Spring Boot + HikariCP 需配合驱动支持,
spring.datasource.hikari.data-source-properties.v$session.module并非所有驱动都认 - PL/SQL 脚本必须在每个逻辑单元入口处重置:
DBMS_APPLICATION_INFO.SET_MODULE('batch-job', 'daily-cleanup')
MODULE 值固定但响应变慢?重点筛 SQL*Net message from client + 长空闲
当多个会话显示相同 MODULE(如 'payment-api')且长期卡在 SQL*Net message from client,这不是数据库慢,是应用“忘了收线”——典型连接池泄漏或客户端未调用 close()。
执行这个查询定位:
SELECT module, machine, COUNT(*) cnt, AVG(last_call_et)/60 avg_min FROM v$session WHERE status = 'INACTIVE' AND event = 'SQL*Net message from client' AND module = 'payment-api' AND last_call_et > 7200 GROUP BY module, machine HAVING COUNT(*) > 5;
-
last_call_et > 7200表示空闲超 2 小时,比 3600 更贴合生产容忍阈值 - 同一
machine下数量突增,说明某台服务器上的 JVM 进程异常,不是全局配置问题 - 若
module是'JDBC Thin Client'这类泛化值,说明应用完全没设,优先推动补全
MODULE 名称带随机后缀?改用 CLIENT_IDENTIFIER 辅助归因
有些应用为规避连接复用问题,把时间戳、线程 ID 拼进 MODULE(如 'report-engine-202607280450'),导致按 MODULE 分组失效。
这时该用 CLIENT_IDENTIFIER:它由应用调用 DBMS_SESSION.SET_IDENTIFIER 设置,更稳定,且 v$active_session_history 和 dba_hist_active_sess_history 都有该字段。
- 应用侧设置示例:
DBMS_SESSION.SET_IDENTIFIER('order-service-v2@host123') - ASH 查询时替换
WHERE module = ...为WHERE client_id LIKE 'order-service-v2%' - RAC 环境下必须用
gv$active_session_history并加AND inst_id = <target_inst></target_inst>,否则数据混杂
为什么 RAC + 多租户下 MODULE 分析容易失真
RAC 实例间采样不严格同步,多租户下 PDB_NAME 又依赖 ALTER SESSION SET CONTAINER 才生效——这两者叠加,会导致同一个 MODULE 的会话样本分散在不同 inst_id 和空 PDB_NAME 记录里。
- 查
gv$active_session_history时,必须同时过滤inst_id和PDB_NAME,不能只靠MODULE - 如果没提前在目标 PDB 内执行
ALTER SESSION SET CONTAINER = pdb_name,PDB_NAME列就是空或CDB$ROOT,和MODULE关联就断了 -
SYS_CONTEXT('userenv', 'con_name')返回的是当前 session 的容器名,但 ASH 采样是后台MMNL进程做的,它不继承你的 session context
最易被忽略的一点:模块分析本身不难,难在确保采样上下文完整——MODULE、CLIENT_IDENTIFIER、PDB_NAME、inst_id 四者必须在同一查询上下文中对齐,缺一不可。











