数据库收缩数据文件的尝试(二)(r11笔记第10天)
在之前自己的一个测试环境中,因为本身磁盘空间不足,导致一个测试库数据目录溢出,最后花了点功夫,将一个2G左右的文件经过收缩的操作后,竟然收缩为7M。详情可以参考 收缩
而隔了很长一段时间后,我在线上一个环境碰到了类似的问题。
这个数据库是一个OLAP的业务库,之前的数据量还不小,大概有1.7T,但是经过业务梳理之后,有一部分业务不需要的数据就删除了,后续迁移了另外一个环境的数据过来。
从资源的规划来看,这个库的数据增长还远远达不到目前的使用量,所以也不用考虑太多的扩容需求,但是问题来了,现在的库已经被撑大了。想要收缩就难了。当前的问题其实挺严峻,下面的磁盘分区已经超过了报警阈值。
/dev/sdb 1.7T 1.5T 127G 92% /U01
但是从DB层面来看,所能做的工作似乎很少。因为尝试resize操作,只能收缩很小的空间。
这里就涉及一个数据文件的“高水位线”问题,大体来说,就是数据文件很大,但是里面的数据分布情况是不均匀的。很可能出现较大的断层,这样一来数据空间使用不充分,但是物理空间却无法轻易释放。造成的一种比较尴尬的情况就是下面的样子。剩余空间1.1T,使用空间才300多G,空间的使用率完全没有合理释放出来。
Tablespace STA M A Init Total MB Free MB Used MB
所以这种情况需要改善,但是收起来容易,做起来难。
因为我很快发现问题比我想的要复杂一些。大体来说数据文件的高水线县问题有三类。
在数据文件的起始位置附近。或者是中间的位置
在数据文件的中间出现较大的断层。
总之,这些位置都有可能出现大量的碎片,使用脚本查看可以收缩的空间,竟然只能省出18M左右的空间。
FILE# CURRENTMB RESIZETO RELEASEMB RESIZECMD
所以这问题还是蛮纠结的。查看数据文件的高水线,对应的脚本如下:
sqlplus -s / as sysdba <<EOF
只需要输入数据文件的id即可。
怎么尽可能全面,快捷的降低高水位线呢,一种方式就是在当前的数据文件中寻找那些空间使用出入较大的对象。
还有一种思路也算比较简单,就是新建一个表空间,然后把数据都迁移到这个表空间。
而通用的思路为了达到高可用性,可以使用在线重定义,或者是基于ROWID的方式来删除,插入数据,因为开启的事务级支持,所以依旧可以,而且操作起来也会有一些思路和方法可以参考。