AWR历史表空间分析依赖DBA_HIST_TBSPC_SPACE_USAGE中压缩的块数数据,需关联DBA_TABLESPACES换算为GB;用REGR_SLOPE拟合30天内日均增长,TRUNC(RTIME)归一化日期防溢出;SYSAUX暴涨多因WRH$_ACTIVE_SESSION_HISTORY积压,删快照前须先调小baseline窗口并确认无静态baseline。
查 AWR 历史表空间使用数据,用 DBA_HIST_TBSPC_SPACE_USAGE
awr 本身不预测增长,但它存了每个快照点的表空间实际用量(精确到 mb),这是做线性趋势分析的唯一可靠依据。别信手工算“每天增多少”,得从历史快照里挖真实数据。
关键点:
-
DBA_HIST_TBSPC_SPACE_USAGE中的TABLESPACE_SIZE和TABLESPACE_USEDSIZE是压缩后的数值,单位是“数据库块数”,必须关联DBA_TABLESPACES拿到BLOCK_SIZE才能换算成 GB - 时间字段
RTIME是 DATE 类型但带时分秒,SUBSTR(RTIME,1,10)取日期要小心——Oracle 12c+ 后部分版本返回格式为'03/15/2026 00:00:00',直接TO_DATE(RTIME, 'mm/dd/yyyy hh24:mi:ss')更稳 - 如果查出来某天多条记录(比如每小时一个快照),建议按
MAX(TABLESPACE_USEDSIZE)聚合,取当日峰值,避免低估
写 SQL 做简单线性拟合,别依赖外部工具
不需要 Python 或 Excel,用 Oracle 自带的 REGR_SLOPE 和 REGR_INTERCEPT 就能算日均增长量。重点不是“有多准”,而是看趋势是否持续上扬、有没有拐点。
实操建议:
- 只对最近 30 天的数据建模,太老的数据可能受扩容、归档策略变更干扰
- 用
TRUNC(RTIME)归一化日期,再转成数字(如TRUNC(RTIME) - DATE '2026-01-01')作为 X 轴,避免日期计算溢出 - 示例片段(以 USERS 表空间为例):
SELECT ROUND(REGR_SLOPE(USED_SIZE_GB, DT_NUM), 3) AS "GB_PER_DAY", ROUND(REGR_INTERCEPT(USED_SIZE_GB, DT_NUM), 3) AS "BASELINE_GB" FROM ( SELECT TRUNC(rtime) - DATE '2026-01-01' AS DT_NUM, ROUND(tablespace_usedsize * block_size / 1024/1024/1024, 3) AS USED_SIZE_GB FROM dba_hist_tbspc_space_usage a, dba_tablespaces b WHERE a.tablespace_id = b.ts# AND b.tablespace_name = 'USERS' AND rtime >= SYSDATE - 30 )
识别异常增长源:先盯 WRH$_ACTIVE_SESSION_HISTORY,再查事件分布
SYSAUX 表空间暴涨,90% 以上都卡在 WRH$_ACTIVE_SESSION_HISTORY 及其索引。它不是“慢查询日志”,而是每秒采样活动会话堆栈的原始快照,体积大、压缩差、删除后还不自动回收空间。
排查步骤:
- 运行
SELECT COUNT(*) FROM WRH$_ACTIVE_SESSION_HISTORY—— 如果超 200 万行,基本可断定是 AWR 采集过频或保留太久 - 确认当前设置:
SELECT SNAP_INTERVAL, RETENTION FROM DBA_HIST_WR_CONTROL,常见坑是把RETENTION设成 30 天但没配MOVING_WINDOW_SIZE,导致 baseline 锁住旧快照删不掉 - 查高产事件:
SELECT EVENT, COUNT(*) FROM V$ACTIVE_SESSION_HISTORY WHERE SAMPLE_TIME > SYSDATE-1 GROUP BY EVENT ORDER BY 2 DESC;若cursor: pin S wait on X占比超 80%,说明应用存在硬解析风暴,得调应用,不是调 AWR
删快照前必须检查 baseline 和 MOVING_WINDOW_SIZE
直接跑 DBMS_WORKLOAD_REPOSITORY.DROP_SNAPSHOT_RANGE 很容易失败,报错 ORA-13516: AWR snapshot range cannot be dropped,根本原因是 baseline 挡路。
安全操作顺序:
- 先查 baseline 窗口:
SELECT MOVING_WINDOW_SIZE FROM DBA_HIST_BASELINE,如果值大于你想删的天数(比如窗口是 8 天,你想删 7 天前的),必须先收缩:BEGIN DBMS_WORKLOAD_REPOSITORY.MODIFY_BASELINE_WINDOW_SIZE(WINDOW_SIZE => 7); END;
- 再确认无自定义 baseline:
SELECT BASELINE_NAME FROM DBA_HIST_BASELINE WHERE BASELINE_TYPE = 'STATIC',有就手动删或禁用 - 最后才删快照:
EXEC DBMS_WORKLOAD_REPOSITORY.DROP_SNAPSHOT_RANGE(LOW_SNAP_ID => 1000, HIGH_SNAP_ID => 1050, DBID => 123456789);注意DBID必须和V$DATABASE.DBID一致,抄错就删错库
删完不会立刻释放 SYSAUX 空间,WRH$_* 表是分区表,得等后续自动维护任务合并分区,或者手动 ALTER TABLE WRH$_ACTIVE_SESSION_HISTORY DROP PARTITION ... —— 但这属于高危操作,没 DBA 支持别碰。

















