Oracle表空间增长量记录来源于DBA_HIST_TBSPC_SPACE_USAGE视图,但该视图依赖AWR快照且默认仅保留8天;长期监控需配合外部脚本定期采集dba_tablespaces等视图数据并落库。
Oracle表空间增长量记录从哪来?
oracle本身不自动记录表空间每日大小,dba_hist_tbspc_space_usage 是唯一可查的历史快照视图,但它依赖 awr(automatic workload repository),且默认只保留 8 天(取决于 retention 设置)。如果你没调大 awr 保留期,查不到 30 天数据是常态,不是 sql 写错了。
实操建议:
- 先确认 AWR 保留天数:
SELECT retention FROM dba_hist_wr_control;
- 若结果小于 30,
DBA_HIST_TBSPC_SPACE_USAGE就不可能有完整 30 天数据;强行查只会返回空或部分结果 - 长期监控必须配合外部脚本定期采集
dba_tablespaces+dba_data_files或dba_segments的汇总值并落库,不能只靠 AWR
用 DBA_HIST_TBSPC_SPACE_USAGE 查最近可用增长数据
该视图每小时采样一次,tablespace_id 和 tablespace_name 对应,used_space 单位是数据库块(block),需乘以 block_size 换算为字节。直接查最近 30 天会漏掉时间对齐问题——AWR 快照不是严格按日切分的。
推荐写法(取每个表空间每天最大已用块数,近似日峰值):
SELECT tablespace_name, TRUNC(snap_time) AS day, MAX(used_space) * (SELECT value FROM v$parameter WHERE name = 'db_block_size') AS bytes_used FROM dba_hist_tbspc_space_usage u JOIN dba_hist_snapshot s ON u.snap_id = s.snap_id AND u.dbid = s.dbid WHERE snap_time >= SYSDATE - 30 GROUP BY tablespace_name, TRUNC(snap_time) ORDER BY tablespace_name, day;
注意点:
-
snap_time是快照生成时间,不是数据写入时间,可能滞后几分钟 - 不同表空间的
block_size可能不同(尤其有 bigfile 表空间时),上面写法假设统一,实际应关联dba_tablespaces取各自block_size - 如果某天无快照(如夜间关闭了统计收集),该日数据就为空,不能简单用
LAG()算差值
如何算“增长量”而不是“占用量”?
真要算每日增长,得用窗口函数做相邻日期差值,但前提是每天都有可靠快照。以下语句只在连续有数据的前提下有效:
SELECT
tablespace_name,
day,
bytes_used,
bytes_used - LAG(bytes_used) OVER (PARTITION BY tablespace_name ORDER BY day) AS daily_growth
FROM (
SELECT
tablespace_name,
TRUNC(snap_time) AS day,
MAX(used_space) * (SELECT value FROM v$parameter WHERE name = 'db_block_size') AS bytes_used
FROM dba_hist_tbspc_space_usage u
JOIN dba_hist_snapshot s ON u.snap_id = s.snap_id AND u.dbid = s.dbid
WHERE snap_time >= SYSDATE - 30
GROUP BY tablespace_name, TRUNC(snap_time)
)
ORDER BY tablespace_name, day;
常见陷阱:
-
LAG()遇到空日期会返回 NULL,导致daily_growth为 NULL,不是 0 —— 别误以为没增长 - 如果表空间当天被 resize 过(如手工扩大数据文件),
used_space可能突降(因 Oracle 重算高水位),造成负增长假象 - 临时表空间、undo 表空间的
used_space波动极大,不适合用此方式看“增长”,更适合看趋势极值
没有 AWR 或权限不足时的替代方案
如果只有普通用户权限,或数据库禁用了 AWR(如 Standard Edition),DBA_HIST_TBSPC_SPACE_USAGE 不可见,只能退回到实时视图拼时间点快照:
- 用
dba_data_files+dba_free_space计算当前总使用量,配合 OS 定时任务每小时执行一次并插入自建历史表 - 关键字段:sum(
bytes) fromdba_data_files减去 sum(bytes) fromdba_free_space,再 group bytablespace_name - 别依赖
dba_segments求和——它不含未格式化的空间,且统计慢、不准 - 务必加时间戳字段(
INSERT_TIME DATE DEFAULT SYSDATE),否则无法回溯
最常被忽略的一点:即使你有 DBA 权限,DBA_HIST_TBSPC_SPACE_USAGE 默认也不包含 SYSAUX、SYSTEM 等核心表空间的细粒度记录,某些版本里它们被聚合进一个伪表空间 ID,得结合 v$tablespace 核对 ts# 映射关系。











