在 Oracle RAC/ODA 环境中,查询数据库空间时一定要分清两个口径:
数据库逻辑空间:Oracle 数据文件/临时文件当前已分配大小
ASM实际占用:考虑 ASM 冗余副本后的真实磁盘组占用
如果 ASM 磁盘组是 HIGH 冗余,通常就是三副本,因此实际占用约为逻辑空间的 3 倍。
一、查询当前 PDB 逻辑已分配空间
先确认当前容器:
show con_name;
在具体 PDB 下执行:
set lines 200
select 'DATAFILE' as file_type,
round(sum(bytes) / 1024 / 1024 / 1024, 2) as allocated_gb
from dba_data_files
union all
select 'TEMPFILE' as file_type,
round(sum(bytes) / 1024 / 1024 / 1024, 2) as allocated_gb
from dba_temp_files;
说明:
DATAFILE:永久表空间数据文件
TEMPFILE:临时表空间文件
这个结果是 数据库逻辑已分配空间,不包含 ASM 三副本,也不包含 autoextend 未来最大可扩展空间。
二、查询 PDB 对应的 ASM GUID 目录
在 CDB$ROOT 下执行:
alter session set container=CDB$ROOT;
set linesize 200
set pagesize 100
col con_id for 999
col name for a20
col guid_hex for a40
col open_mode for a15
select con_id,
name,
rawtohex(guid) as guid_hex,
open_mode
from v$pdbs
order by con_id;
示例:
CON_ID NAME GUID_HEX OPEN_MODE
------ ---------- ---------------------------------------- ----------
3 YJXT 4F6774285AC51A9E0630B0D020260519 READ WRITE
7 ECOLOGY 41D0938DC57A00CEE0630B0D20260519 READ WRITE
这里的 GUID_HEX 就是 PDB 在 ASM 里的目录名。
set...和col...是 SQL*Plus 显示格式控制命令
| 命令 | 作用 |
|---|---|
set linesize 200 |
设置每行显示宽度为 200 个字符,避免结果换行 |
set pagesize 100 |
设置每页显示 100 行,减少表头频繁重复 |
col con_id for 999 |
设置 con_id 显示为最多 3 位数字 |
col name for a20 |
设置 name 字符列宽度为 20 个字符 |
col guid_hex for a40 |
设置 guid_hex 字符列宽度为 40 个字符 |
col open_mode for a15 |
设置 open_mode 字符列宽度为 15 个字符 |
如果不设置,结果可能会变成这样,字段被折行:
CON_ID
------
NAME
--------------------------------------------------------------------------------
GUID_HEX
----------------------------------------------------------------
OPEN_MODE
--------------------
三、使用 ASMCMD 查询 PDB 实际占用
切换到 grid 用户:
su - grid
查询 PDB 目录大小:
asmcmd du +DATA/ERPCDB/4F6774285AC51A9E0630B0D020260519
asmcmd du +DATA/ERPCDB/41D0938DC57A00CEE0630B0D20260519
输出示例:
Used_MB Mirror_used_MB
310056 930168
Used_MB Mirror_used_MB
1036784 3110352
字段含义:
Used_MB :逻辑占用,不含 ASM 副本
Mirror_used_MB :ASM 实际占用,包含三副本
如果要直接转成 GB,可以这样写:
asmcmd du +DATA/ERPCDB/4F6774285AC51A9E0630B0D020260519 | awk 'NR==2 {printf "YJXT Used_GB=%.2f GB, Mirror_used_GB=%.2f GB\n", $1/1024, $2/1024}'
asmcmd du +DATA/ERPCDB/41D0938DC57A00CEE0630B0D20260519 | awk 'NR==2 {printf "ECOLOGY Used_GB=%.2f GB, Mirror_used_GB=%.2f GB\n", $1/1024, $2/1024}'
示例结果:
YJXT Used_GB=302.79 GB, Mirror_used_GB=908.37 GB
ECOLOGY Used_GB=1012.48 GB, Mirror_used_GB=3037.45 GB
对外汇报实际磁盘占用时,重点看:
Mirror_used_GB
四、使用 V$ASM_FILE 查询当前 PDB 的 ASM 占用
如果要用 SQL 查询某个 PDB 的 ASM 文件空间,先切换到具体 PDB:
alter session set container=ECOLOGY;
然后执行:
set linesize 200
set pagesize 100
col file_type for a20
select nvl(type, 'TOTAL') as file_type,
round(sum(bytes)/1024/1024/1024,2) as logical_gb,
round(sum(space)/1024/1024/1024,2) as asm_allocated_gb
from v$asm_file
where type in ('DATAFILE','TEMPFILE')
group by rollup(type)
order by case when type is null then 2 else 1 end, type;
字段含义:
LOGICAL_GB :逻辑大小,不含副本
ASM_ALLOCATED_GB :ASM 实际分配大小,包含三副本
示例:
FILE_TYPE LOGICAL_GB ASM_ALLOCATED_GB
DATAFILE 891.47 2675.19
TEMPFILE 120.71 362.26
TOTAL 1012.17 3037.45
说明:
ECOLOGY 逻辑空间约 1012.17GB
ASM 三副本后实际占用约 3037.45GB
五、确认 ASM 是否三副本
使用 grid 用户执行:
asmcmd lsdg
重点看 Type 字段:
State Type Name
MOUNTED HIGH DATA/
MOUNTED HIGH RECO/
含义:
EXTERN:ASM 不做副本
NORMAL:通常双副本
HIGH :通常三副本
如果 Type = HIGH,说明该 ASM 磁盘组是高冗余三副本。
也可以用 SQL 查:
su - grid
sqlplus / as sysasm
set lines 200
col name for a15
col type for a10
col state for a12
select name,
state,
type,
total_mb,
free_mb,
usable_file_mb
from v$asm_diskgroup_stat;
六、最终口径总结
| 查询目的 | 使用方法 | 是否包含三副本 |
|---|---|---|
| 查 PDB 逻辑已分配空间 | DBA_DATA_FILES + DBA_TEMP_FILES |
不包含 |
| 查 PDB ASM 实际占用 | asmcmd du +DATA/CDB/GUID |
看 Mirror_used_MB |
| 查 SQL 版 ASM 占用 | V$ASM_FILE |
看 SPACE / ASM_ALLOCATED_GB |
| 查 ASM 是否三副本 | asmcmd lsdg |
看 Type=HIGH |
一句话总结:
DBA_DATA_FILES / DBA_TEMP_FILES 查的是逻辑大小;
ASMCMD DU 的 Mirror_used_MB 和 V$ASM_FILE.SPACE 查的是 ASM 三副本后的实际占用。
如果是容量表或领导汇报,建议这样写:
逻辑分配空间:xxxx GB
ASM三副本实际占用:xxxx GB
备注:ASM磁盘组为HIGH冗余,实际占用按Mirror_used_MB或V$ASM_FILE.SPACE统计。
或者用表格

这样口径清楚,不会把"逻辑大小"和"三副本实际占用"混在一起。
