多租户下须用CON_ID生成PDB专属AWR报告,否则CDB级汇总掩盖PDB级争用;查v$pdbs获CON_ID,调用awrrpt时显式传参,Top SQL和等待事件需按PDB隔离分析,并确保基线与问题时段的CON_ID、DBID、快照窗口严格一致。

多租户环境下直接看默认AWR报告会漏掉PDB级争用——CDB级汇总把各PDB的CPU、I/O、锁等待全混在一起,DB CPU Per Sec或enq: TX - row lock contention飙升时,你根本不知道是哪个PDB在拖后腿。
必须用CON_ID过滤生成PDB专属AWR报告
默认@?/rdbms/admin/awrrpt脚本输出的是CDB全局视图,所有统计都按实例+时间聚合,CON_ID字段被隐式忽略。不显式指定PDB上下文,等于拿混合果汁当纯橙汁喝。
- 先查目标PDB的
CON_ID:SELECT con_id, name FROM v$pdbs WHERE name = 'HR_PDB'; - 生成报告时传
con_id参数(SQL*Plus中):DEFINE CON_ID = 3,再执行@?/rdbms/admin/awrrpt - 若用
DBMS_WORKLOAD_REPOSITORY.AWR_REPORT_TEXTPL/SQL调用,第5个参数必须填con_id,传0=全局,传非0=指定PDB - 注意:12c R2起支持
awrrpti脚本(i代表instance),但awrrpti仍不支持con_id,必须用awrrpt并手动传参
PDB级Top SQL和等待事件要看“Per Exec”而非总量
同一SQL在CDB级报告里可能排不进Top 10,但在某个PDB里却是CPU黑洞——因为它的执行集中在那个PDB,而其他PDB几乎不用它。总量排序会掩盖这种局部爆发。
- 重点看
SQL ordered by CPU Time节里的CPU per Exec列,而非Total CPU Time;单次执行超5秒且Executions per Sec > 0.05的语句,大概率是该PDB的瓶颈源 - 等待事件要结合
CON_ID查dba_hist_active_sess_history:SELECT event, COUNT(*) FROM dba_hist_active_sess_history WHERE con_id = 3 AND sample_time > SYSDATE-1/24 GROUP BY event ORDER BY 2 DESC; - 特别警惕
enq: TS - contention(临时表空间争用)和library cache: mutex X(共享池争用),这两类在PDB间资源未隔离时极易跨容器传染
对比基线必须同CON_ID、同快照窗口、同DBID
拿PDB A的问题时段报告和PDB B的“正常”时段报告对比,结果毫无意义。更危险的是用同一PDB的报告,但快照没对齐——比如基线用的是snap_id 1000–1010(间隔30分钟),问题用1050–1060(间隔10分钟),Avg Active Sessions数值直接失真。
- 确认快照归属:
SELECT snap_id, begin_interval_time, con_id, dbid FROM dba_hist_snapshot WHERE snap_id IN (1000,1010,1050,1060) ORDER BY snap_id;,四者con_id和dbid必须完全一致 - 避免用
num_days参数生成报告,改用start_snap_id/end_snap_id硬编码,防止NLS_DATE_FORMAT或会话时区导致时间解析偏移 - RAC下额外加
inst_num,否则即使con_id对了,也可能只取当前连接节点的数据,掩盖跨节点GC争用
最常被跳过的一步:查v$containers确认PDB状态是否为OPEN且CON_UID未被重用。曾有案例因PDB反复拔插导致CON_ID复用,旧快照里的con_id=5实际指向新PDB,所有分析全错。生成报告前花30秒执行SELECT con_id, open_mode, con_uid FROM v$containers;能省去半天排查时间。


















