ASH默认不区分PDB,必须显式过滤CON_ID;V$ACTIVE_SESSION_HISTORY数据混存于CDB级,需先查V$PDBS获取目标PDB的CON_ID再过滤;历史分析用DBA_HIST_ACTIVE_SESS_HISTORY(需CDB$ROOT权限);锁争用排查须关联CON_ID;生成PDB专属ASH报告应使用awrsqrpti.sql而非awrrpti.sql。

ASH默认不区分PDB,必须显式过滤CON_ID
Oracle 19c的ASH数据(V$ACTIVE_SESSION_HISTORY)物理上存储在CDB级别,所有PDB的采样都混在一起。不加CON_ID条件直接查,看到的是整个CDB的活跃会话,根本分不清哪个SQL来自哪个PDB。你执行SELECT * FROM V$ACTIVE_SESSION_HISTORY WHERE SAMPLE_TIME > SYSDATE - 1/24,结果里CON_ID列全是0或随机值,这不是数据丢了,是没按租户维度筛。
正确做法是:先确认目标PDB的CON_ID,再用它过滤ASH。查法如下:
- 连接到CDB$ROOT,运行
SELECT CON_ID, NAME FROM V$PDBS WHERE NAME = 'YOUR_PDB_NAME'; - 拿到
CON_ID后,在ASH查询中强制加入WHERE CON_ID = - 别依赖
SESSION_ID或SQL_ID反推PDB——同一个SQL_ID可能在多个PDB里执行,且V$SESSION里的CON_ID和ASH里的不一定实时对齐
DBA_HIST_ACTIVE_SESS_HISTORY不是实时数据,但支持PDB归档分析
如果问题发生在几小时前,V$ACTIVE_SESSION_HISTORY内存缓冲区可能已被覆盖(默认保留约1小时),这时得查历史ASH视图DBA_HIST_ACTIVE_SESS_HISTORY。它和AWR快照绑定,每小时自动归档一次,且CON_ID字段完整保留。
注意两点:
- 该视图需要
SELECT_CATALOG_ROLE或DBA权限,普通PDB用户即使连进自己PDB也查不到——必须从CDB$ROOT查 - 时间范围要对齐快照ID:
SELECT SNAP_ID, BEGIN_INTERVAL_TIME FROM DBA_HIST_SNAPSHOT WHERE BEGIN_INTERVAL_TIME > SYSDATE - 1,再用SNAP_ID关联ASH记录 - 字段
CON_ID、PDB_NAME(19c新增)、SQL_ID、EVENT、SESSION_STATE全都有,可直接做PDB级Top SQL或等待事件聚合
用ASH定位PDB内锁争用时,BLOCKING_SESSION和BLOCKING_SESSION_SERIAL#需配合CON_ID一起查
当某个PDB响应变慢,怀疑是内部锁导致,光看EVENT = 'enq: TX - row lock contention'不够。因为阻塞者(BLOCKING_SESSION)可能在另一个PDB里,或者同一PDB但不同容器上下文。
关键操作是两表关联:
- 先查出被阻塞会话:
SELECT SESSION_ID, SESSION_SERIAL#, CON_ID, BLOCKING_SESSION, BLOCKING_SESSION_SERIAL#, EVENT FROM V$ACTIVE_SESSION_HISTORY WHERE CON_ID =AND EVENT = 'enq: TX - row lock contention' AND ROWNUM - 再用阻塞者的
SESSION_ID和SESSION_SERIAL#去V$SESSION查详情:SELECT SID, SERIAL#, CON_ID, USERNAME, SQL_ID, STATUS FROM V$SESSION WHERE SID =(AND SERIAL# = AND CON_ID IN ( , 1) CON_ID=1代表CDB$ROOT,有些后台锁可能源于根容器) - 漏掉
CON_ID条件,很可能把阻塞源错判成当前PDB内的会话,实际是CDB级对象(如数据字典表)被锁
生成PDB专属ASH报告要用awrsqrpti.sql而非awrrpti.sql
SQL*Plus里手动生成ASH报告时,很多人习惯用@?/rdbms/admin/awrrpti.sql,但它输出的是CDB整体报告,PDB信息被折叠。真正支持PDB粒度的是awrsqrpti.sql(SQL Report Interactive),它能按CON_ID切片。
执行步骤:
- 确保已连接到CDB$ROOT:
sqlplus / as sysdba - 运行
@?/rdbms/admin/awrsqrpti.sql,过程中会提示输入CON_ID(填你要分析的PDB的ID) - 报告里会出现“Pluggable Database Name”字段,所有SQL统计、等待事件、会话分布都限定在该PDB内
- 如果误用了
awrrpti.sql,报告顶部只会写“Database ID”和“Instance Number”,看不到PDB名,等于白跑
最易忽略的一点:awrsqrpti.sql生成的报告里,SQL_ID对应的执行计划默认不显示PDB名称,需手动在DBA_HIST_SQL_PLAN中用CON_ID过滤才能确认该计划是否属于目标PDB——否则可能把CDB$ROOT里解析的游标当成PDB的。











