必须先切换到目标pdb再查,否则v$active_session_history和dba_hist_*视图里的pdb_name为空或为cdb$root;这是因为oracle 19c的采样机制要求后台进程mmnl在对应pdb上下文中运行才能填充pdb_name,且awr历史视图虽含多pdb数据,但关键字段需显式切换容器才显示真实值。

必须先切换到目标PDB再查,否则V$ACTIVE_SESSION_HISTORY和DBA_HIST_*视图里的PDB_NAME为空或为CDB$ROOT——这不是权限问题,是Oracle 19c的采样机制决定的。
为什么在CDB$ROOT里查不到各PDB的AWR数据
AWR快照本身按实例维度采集,DBA_HIST_SNAPSHOT、DBA_HIST_SQLSTAT等历史视图在CDB$ROOT中确实包含所有PDB的数据,但关键字段如PDB_NAME、CON_ID在未显式切换容器时不会自动填充真实值;V$ACTIVE_SESSION_HISTORY更严重:它的PDB_NAME列默认不写入,除非后台采样进程(MMNL)运行在对应PDB上下文中。
常见错误现象:
- 执行
SELECT DISTINCT pdb_name FROM dba_hist_sqlstat返回空或全是CDB$ROOT - 用
SYS_CONTEXT('userenv', 'con_name')看到当前是PDB01,但查出的ASH记录PDB_NAME仍是NULL - AWR报告生成时提示
Enter value for awr_location:,选AWR_ROOT后报告里SQL列表没有PDB Name列
如何正确查看指定PDB的AWR性能数据
核心动作只有一条:ALTER SESSION SET CONTAINER = pdb_name;,且必须在执行任何AWR相关查询或脚本前完成。
实操建议:
- 用
sqlplus / as sysdba登录后,第一句就执行ALTER SESSION SET CONTAINER = pdb01;(替换成你的PDB名) - 确认已生效:运行
SELECT SYS_CONTEXT('userenv', 'con_name') FROM dual;,输出必须是你刚设的PDB名 - 查ASH:直接运行
SELECT sql_id, event, pdb_name FROM v$active_session_history WHERE sample_time > SYSDATE - 1/24 AND rownum ,检查<code>PDB_NAME是否非空 - 查历史SQL:用
SELECT sql_id, executions_delta, elapsed_time_delta/1000000 sec_delta, pdb_name FROM dba_hist_sqlstat NATURAL JOIN dba_hist_snapshot WHERE snap_id IN (SELECT MAX(snap_id) FROM dba_hist_snapshot) AND ROWNUM
生成PDB专属AWR报告的两个可靠路径
Oracle 12.2+支持两种方式,区别在于快照来源和是否启用PDB级自动刷新:
-
方式一(推荐新手):不改任何参数,只切容器后跑脚本
执行ALTER SESSION SET CONTAINER = pdb01;→ 运行@?/rdbms/admin/awrrpt.sql→ 提示Enter value for awr_location:时输入AWR_ROOT(默认)→ 报告里会显示PDB Name列,数据来自CDB级快照DBA_HIST_SNAPSHOT -
方式二(适合长期监控):启用PDB级快照
先执行ALTER SYSTEM SET awr_pdb_autoflush_enabled = TRUE;→ 再调用DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS设置间隔 → 此后生成报告时可选AWR_PDB,数据来自AWR_PDB_SNAPSHOT基表,隔离性更强
注意:AWR_PDB模式需确保SYSAUX表空间有足够空间,且AWR_SNAPSHOT_TIME_OFFSET参数不宜设为0(避免多PDB快照时间冲突)。
容易被忽略的兼容性细节
不是所有视图都带PDB_NAME字段,也不是所有PDB都能查到完整ASH:
-
DBA_HIST_SYSTEM_EVENT有CON_ID但无PDB_NAME,需JOIN CDB_PDBS USING(CON_ID)补全 - RAC环境下,
V$ACTIVE_SESSION_HISTORY默认只反映本地实例采样,跨实例PDB等待事件需查GV$ACTIVE_SESSION_HISTORY并加INST_ID过滤 - 若PDB处于
READ ONLY状态,AWR_SNAPSHOT_TIME_OFFSET设置可能失败,此时只能依赖CDB级快照(AWR_ROOT) -
DBA_HIST_SEG_STAT中的OBJ#是对象号,不是DATA_OBJECT_ID,跨PDB对比段IO时务必结合CON_ID和OBJ#联合定位
最常被跳过的一步:查完一个PDB后,忘记ALTER SESSION SET CONTAINER = CDB$ROOT;就去切下一个PDB——这会导致后续连接残留上下文,PDB_NAME列再次为空。











