必须在CDB$ROOT中查询cdb_tablespace_usage_metrics视图,因该视图仅在CDB级可见,PDB中执行会报ORA-00942;且需确认目标PDB为OPEN状态、当前会话在CDB$ROOT、视图已刷新(约1分钟延迟)。

直接查 cdb_tablespace_usage_metrics 视图,但必须在 CDB$ROOT 容器下执行,且需确保目标 PDB 处于 OPEN 状态;否则数据为空或滞后。
为什么不能在PDB里查表空间用量?
因为 cdb_tablespace_usage_metrics 是 CDB 级视图,只在 CDB$ROOT 中可访问。你在某个 PDB 里连上去执行 SELECT,会报 ORA-00942: table or view does not exist —— 不是权限问题,是对象根本不可见。
常见错误现象:
- 用
sqlplus user@pdb_name连进 PDB 后直接跑查询,失败 - 误以为
dba_tablespace_usage_metrics存在(实际不存在) - 用
show con_name看着是 PDB,却忘了切回 CDB$ROOT 就去查监控视图
查之前必须确认的三件事
缺一不可,否则结果不准或查不到数据:
-
SELECT name, open_mode FROM v$pdbs确认目标 PDB 是READ WRITE,不是MOUNTED或READ ONLY -
SHOW CON_NAME或SELECT SYS_CONTEXT('USERENV', 'CON_NAME') FROM DUAL确保当前会话在CDB$ROOT - 该视图每分钟自动刷新一次,若刚建完 PDB 就查,可能要等 60 秒才出现首条记录
怎么查才准:过滤 + 四舍五入 + 按 PDB 分组
别直接 SELECT *,容易看花眼。推荐这个最小可用查询:
SELECT con_id, (SELECT name FROM v$pdbs WHERE con_id = t.con_id) con_name, tablespace_name, ROUND(used_space / 1024 / 1024, 2) used_mb, ROUND(tablespace_size / 1024 / 1024, 2) total_mb, ROUND((used_space / tablespace_size) * 100, 1) pct_used FROM cdb_tablespace_usage_metrics t WHERE tablespace_size > 0 ORDER BY con_id, pct_used DESC;
关键点说明:
-
WHERE tablespace_size > 0排除临时表空间(其tablespace_size为 0,used_space可能非零,导致除零或负百分比) - 子查询取
v$pdbs.name是为了显示可读的 PDB 名,con_id数字本身没业务意义 - 不要依赖
used_percent字段——它有时滞后、有时为 NULL,自己算更稳
查到异常高占用后下一步做什么?
视图只告诉你“用了多少”,不告诉你“谁在用”。此时要进对应 PDB 执行:
SELECT owner, segment_name, segment_type, bytes/1024/1024 mb FROM dba_segments WHERE tablespace_name = 'YOUR_TS_NAME' ORDER BY bytes DESC FETCH FIRST 5 ROWS ONLY;
注意:dba_segments 必须在目标 PDB 内查,且用户要有 SELECT_CATALOG_ROLE 或 DBA 权限。漏掉这步,光看用量数字等于没诊断。
最常被忽略的是:PDB 表空间用量突增往往来自未清理的审计日志、归档作业残留或应用未关闭的临时大对象——这些不会出现在 cdb_tablespace_usage_metrics 的历史趋势里,得靠 dba_segments 定位具体对象。











