awr报告不显示segment增长排名,因其“top segments”仅反映访问热度(如逻辑读/物理读),而非空间变化;真正记录段级空间增长的是dba_hist_seg_stat视图,需通过跨快照比对space_used字段计算增量。
awr报告本身不直接显示top segments的增量,但dba_hist_seg_stat是唯一能回溯段级历史增长的来源;想定位“谁在暴涨”,必须跳过awr报告界面,直查历史段统计视图。
为什么不能在AWR报告里直接看到Segment增长排名
AWR报告中的“Top Segments by Logical Reads”或“Physical Reads”只反映某段时间内的访问热度,不是空间增长量。即使某张表被疯狂INSERT,只要没触发高逻辑读(比如走索引插入+无大查询),它根本不会出现在这个列表里——但它的数据文件可能已经悄悄涨了20GB。
真正记录段空间变化的是DBA_HIST_SEG_STAT,它每小时采集一次segment_name、owner、space_used(单位:bytes)等字段,且带snapsot_id和dbid,支持跨快照比对。
- AWR报告里的“Segments”章节只是静态快照点的快照,没有时间维度差值计算
-
DBA_HIST_SEG_STAT中space_used字段在19c中才稳定可用;12c及以前版本该列常为NULL - 该视图默认保留8天,若需查更久前的增长,得确认
dba_hist_wr_control中retention是否调长过
怎么用DBA_HIST_SEG_STAT查出最近7天增长最多的10个Segment
核心思路是:取两个相邻快照(如最新快照与7天前快照),对每个owner+segment_name做MAX(space_used)聚合后相减,再排序。
执行前先确认目标快照范围:
SELECT MIN(snap_id) min_snap, MAX(snap_id) max_snap FROM dba_hist_snapshot WHERE snap_time >= SYSDATE - 7;
再运行增长计算SQL(示例以USERS表空间为例):
WITH base AS (
SELECT owner, segment_name,
MAX(CASE WHEN snap_id = &min_snap THEN space_used END) AS used_before,
MAX(CASE WHEN snap_id = &max_snap THEN space_used END) AS used_after
FROM dba_hist_seg_stat s
JOIN dba_segments d ON s.owner = d.owner AND s.segment_name = d.segment_name
WHERE s.snap_id IN (&min_snap, &max_snap)
AND d.tablespace_name = 'USERS'
GROUP BY owner, segment_name
)
SELECT owner, segment_name,
ROUND((used_after - used_before)/1024/1024, 2) AS "GROWTH_MB"
FROM base
WHERE used_after > used_before
ORDER BY "GROWTH_MB" DESC
FETCH FIRST 10 ROWS ONLY;
-
&min_snap和&max_snap替换成上一步查出的实际ID - 必须
JOIN dba_segments过滤表空间,否则DBA_HIST_SEG_STAT包含所有段(含SYSTEM、SYSAUX内部对象) - 若结果为空,检查
space_used是否全为NULL——可能是19c之前版本,或统计未启用(确认ALTER SYSTEM SET "_kghdsidx_count"=0未误设)
查到暴涨Segment后,下一步必须交叉验证ASH和DDL日志
知道哪张表涨得快只是开始,关键要判断是正常业务写入,还是异常行为(如未分区日志表、漏删的ETL临时表、审计开关失控)。
- 查该段最近是否有高频INSERT/APPEND:去AWR报告的“SQL Statistics”页,按
Executions排序,搜INSERT INTO <segment_name></segment_name>或/*+ APPEND */关键字 - 查会话行为:用
DBA_HIST_ACTIVE_SESS_HISTORY反查该段被修改时的sql_id和session_type,重点关注BACKGROUND会话(如MMON、SMCO)是否在刷WRH$_表 - 查DDL变更:运行
SELECT * FROM dba_audit_trail WHERE obj_name = '<segment_name>' AND action_name = 'CREATE' ORDER BY timestamp DESC</segment_name>,确认是否近期建了新分区或启用了行移动
最易被忽略的是:DBA_HIST_SEG_STAT里的space_used包含已分配但未使用的空间(如ALTER TABLE ... ALLOCATE EXTENT预分配),所以看到“暴涨”别急着删数据,先用DBMS_SPACE.SPACE_USAGE确认真实占用率。











