风险提示
在某些版本较低的Oracle数据库中,可能会出现表空间莫名奇妙的增加。如果你和本文描述的几点都吻合,你可能遇到了Oracle Bug。如果你的数据库版本低于10.2.0.4.3,建议你赶快排查风险。本文末尾会介绍如何确认你的系统是否遭遇这个bug。
历史故障回放
2010年12月2日凌晨1点,XX系统生产环境索引表空间XXXIND使用率涨至100%,触发红色告警事件。已经造成业务中断。
检查两个小时的告警结果对比,12月1日凌晨1点表空间free为70,使用率30%,到了12月1日凌晨2点,表空间使用率free为0,使用率达到了100%,这和告警信息吻合。
空间都去哪了
从以下输出可以看到,表空间大小12月1日只使用了4965M,到了12月2日使用了16561M,短短一天时间使用超过10G。
由于这个表空间是业务表空间,而应用人员反馈这段时间没有大的数据插入动作。那么空间都去哪了?
一个神奇的视图
ORACLE数据库提供了一个比较冷僻的视图,WRH$_TABLESPACE_SPACE_USAGE(oracle 10g版本后提供),该视图记录了每个小时表空间的使用情况。如果表空间使用率满,则会记录表空间满的时间段。
创建了大对象?
检查未发现有新的对象被创建。排除该可能。是否某个对象突然变大呢?
如果存在表中突然加载了大量数据的情况,那么表空间内的表段、索引段等对象的大小将会变大。因此需要检查该表空间内最占空间的段是哪个。
从上述查询结果可以看到,该表空间内大于1G的段有一个,为XXX_PK索引段。
索引怎么了?
空间泄露?
检查表字段的个数,发现表中的字段非常多,表的平均行长远大于索引字段+rowid。表实际有将近100列。
如何检查空间分配
可以看到,索引中的Unformatted Blocks 达到了 740681,远远大于真正占用空间(5600+49427)。
也就是说,索引把表空间所有未格式化的block据为己有,但是却未使用。这是空间泄漏的明显表现。
通过对比Full Blocks和FS2的和Unformatted Blocks的值,两者相差甚远,那么可能遭遇索引空间泄露或者碎片。
并同时对比索引和表的大小,如果索引比表大很多。基本可以确定是bug。
监控方法:
除了监控表空间使用率外,还要监控表空间的周期增量是否有异常。
确认bug
以“Unformatted Blocks”为关键字,在ORACLE METALINK BUG库中搜索空间泄漏的相关BUG,可找到多个类似的BUG,其基本BUG均为 5890312。以下是该BUG的详细资料。该BUG在9.2.0.8、10.2.0.3和10.2.0.4版本中出现并被ORACLE确认。该BUG在PSU 10.2.0.4.3和10.2.0.5 PATSET中得到了修复。
解决方案
临时方案:可以临时重建索引,回收空间。
根本解决方案:
Ø 安装PSU补丁至10.2.0.4.3
Ø 安装10.2.0.5 PATCHSET
或者升级到更高版本。