inthirties 老大,小弟現在有這樣的問題.
我有一個數據庫,原來數據庫容量大約17G,表空間我一直設置的是自動增長,現在
我刪除了幾個比較大的表,數據庫容量變為14G,但是表空間容量沒有變,只是表空
間利用率變為80%了,因為我現在數據不會增加了(測試環境),我想把硬盤空間滕
出來,也就是碎片整理,讓現在的表空間里利用率提高至95%以上.
請老大給出我解決的方法.

解决方案 »

  1.   

    1.导出数据,然后重新创建数据库在导入;
    2.resize表空间
      

  2.   

    你可以RESIZE DATAFILE
    ALTER DATABASE DATAFILE ... RESIZE ..
      

  3.   

    如果数据文件被更新,RESIZE操作是不允许的,刚创建的表空间还行。把数据导出后,将表空间删除重建,再导入吧。
      

  4.   

    如果是10G的话,可以通过,10以前的,看前面的人的回答alter segment shrink来收回空间
      

  5.   


    汗,写了忘记提交,只好在写过一次了。对于table空间的收缩是一个老生常谈的问题,不过却是一个一直都没有很透彻的讨论清楚过的问题。借ks_reny的机会,谈谈个人看法,有不及之处,希望高手引领更深入研究此话题。datafile是物理上的一个文件在下层就是基于文件系统的block块了,而我们经常提到的segment,extent,数据库的block,这里都是oracle存储是的逻辑上的单位,所以首先设想一下如果是你来实现delete或者drop的操作的时候,你会是真正的调用文件系统的API,而重新把datafile重新整理一遍吗,我想你也不会如此的吧。这样的话,每个delete或者是drop的操作将会带来我们更多的痛苦。所以Oracle更不会如此,这就是为什么你的datafile的大小并没有发生变化的原因,那么,文件系统上虽然没有重新修理datafile,但是oracle里却通过自己的实现,通过对内部逻辑单元的处理,在逻辑上已经删除了那些单元,从而storage manage知道以后如果需要的连续block这里可以满足的话,就把这个碎片填上了。 所以对于oracle来说,他很清楚这里是可用的,这样利用率也就小了变话了。所以这里要解决你的问题就要使我们的datafile瘦身,只有datafile瘦下来了,你的data又不变化了,利用率也就上升了。那么如果让你的datafile瘦下来了,1. exp/imp  expdp/impdp 这个虽然原始,也比较繁琐,但是确实是一个非常稳定可靠的方法。2. resize  resize面临一个问题,resize到多大,大了没有意义,小了出现错误。
    这里特地写了一个sql脚本,你可以使用运行这个脚本的结果,就是你指定的file做resize的命令SQL> variable blocksize number;
    SQL> begin execute immediate 'select value from v$parameter where name = ''db_block_size''' into :blocksize; end;
        2 /
    SQL>print :blocksize;
    SQL> select 'alter database datafile ''' ||
      2   file_name || ''' resize ' ||
      3   ceil( nvl(hwm,1)*:blocksize/1024/1024 ) || 'm;' cmd
      4  from dba_data_files a,
      5      ( select file_id,
      6          max(block_id+blocks-1) hwm
      7          from dba_extents
      8         group by file_id ) b
      9  where a.file_id = b.file_id(+) and b.file_id in (7, 8, 10);CMD
    --------------------------------------------------------------------------------alter database datafile 'F:\DEVELOPER\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\TEST\TESTTS1.02.DBF' resize 18m;
    alter database datafile 'F:\DEVELOPER\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\TEST\TESTTS1.01.DBF' resize 5m;
    alter database datafile 'F:\DEVELOPER\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\TEST\TESTTS1.03.DBF' resize 40m;执行这里的sql语句就可以了,不过这里注意了,这里可以看到,实际上是用最大的blocks作为resize的标准,如果size超过,或者是已经扩展过的block 就会出现 文件包含在请求的 RESIZE 值以外使用的数据 的错误了,所以这个方法,可行但是并不是很实际。这样的case基本上只在做练习的时候出现。3. 如果你是一个表或者少量的表在那个表空间,可以通过creat table as select ...的方式或者move的方式,move完成后再干掉表空间,干掉表空间的时候,including contents and datefiles就可以了。刚才写了一次,忘记提交了,只好有写过一次。我将开一个blog文来整理有关shrink的问题。 大家可以继续关注。顺便,好像11g里有shrink tablespace的feature,不过还没有研究过,有兴趣你自己找找看。
      

  6.   

    Mark 和 收藏.相信inthirties.
      

  7.   

    是的,其实我这里是推荐用exp/imp,