关于收缩数据文件的尝试

在数据库中对于数据文件都是提前规划,不够就加的情况,很少会留意到其实有些数据文件那么大,其实条件允许也是可以收缩收缩的。
这种情况在本地测试环境中尤为突出,本来就用虚拟机跑个数据库,硬盘空间就够紧张,几十M几百M都是空间,都得“兆兆”计较。
今天在做dataguard的练习的时候,发现主库中的数据文件有些大,差不多4G左右,其实这个库里也没有装什么特别的东西,都是些测试表,完全可以清楚,使用dba_segments查看了下,有一个测试表在2G左右,占了不少的空间,基本一个数据文件都占完了。
FILE_NAME                                                  BYTES
----------------------------------------------------------------------------------------
/u02/ora11g/oradata/TEST11G/users01.dbf     2187329536

看来清除以后能节省不少的空间,就使用drop table xxxx purge;给清理了,但是发现数据文件的大小还是丝毫没有改变。

我使用下面的语句简单验证了一下,表空间USER占用的情况在300M左右。
> select sum(bytes) --,segment_name 
       from dba_segments
       where tablespace_name='USERS';
SUM(BYTES)--,SEGMENT_NAME
-------------------------
                 31129600
为了尽可能多的释放更多空间,我又删了几个分区表,感觉应该剩下不少空间了。
就使用如下的语句来生成resize语句来收缩一下数据文件(我建的这个表空间只有一个数据文件)
select a.file#,a.name,a.bytes/1024/1024 CurrentMB,
          ceil(HWM * a.block_size)/1024/1024 ResizeTo,
          (a.bytes - HWM * a.block_size)/1024/1024 ReleaseMB,
          'alter database datafile '''||a.name||''' resize '||
          ceil(HWM * a.block_size/1024/1024) || 'M;' ResizeCMD
   from v$datafile a,
        (select file_id,max(block_id+blocks-1) HWM
          from dba_extents
          group by file_id) b
  where a.file# = b.file_id(+)
   and (a.bytes - HWM *block_size)>0
生成的语句如下:
alter database datafile '/u02/ora11g/oradata/TEST11G/users01.dbf' resize 2076M;

可以看到基本没有任何改变,但是根据我的直观感觉,确实没有多少表了,空间也确实都腾出来了。
可以简单的验证一下,数据文件是4号,使用dba_extents可以看到占用的空间情况和对应的块的情况。
> select file_id,max(block_id+blocks-1) HWM,block_id
             from dba_extents
             where file_id=4
             group by file_id,block_id;

   FILE_ID        HWM   BLOCK_ID
---------- ---------- ----------
         4        447        440
         4        255        248
         4        543        536
         4        159        152
         4        415        408
         4        479        472
         4        463        456
         4        495        488
         4        679        672
         4     263871     263864
         4        151        144
         4        455        448
         4        623        616
         4        631        624
         4        535        528
         4        551        544
         4        895        768
         4     263847     263840
         4        191        184
         4        311        304
         4        327        320
         4        527        520
         4        399        392
         4        407        400
         4        431        424
         4        567        560
         4        591        584
         4        639        632
         4     265639     265632
         4     265647     265640
         4        239        232
         4        247        240
         4        303        296
         4        511        504
         4        519        512
         4        703        696
         4        167        160
         4        559        552
         4        599        592
         4     265655     265648
  ......

标黄的部分都是空间占用差别比较大的。我们来在这个基础上做一个简单的分析。
首先得到4号数据文件中,块号最大的数据块block_id
> SELECT MAX(block_id)
      FROM dba_extents
     WHERE tablespace_name = 'USERS'; 
MAX(BLOCK_ID)
-------------
       265648     
然后简单换算一下,可以得到“对应”的数据文件是2G左右,这个就和最开始碰到的情况吻合了。
> SELECT 265648*8192/1024/1024 FROM dual;
265648*8192/1024/1024
---------------------
             2075.375

看看这个数据块所在的extent对应的segment信息。
> select segment_name,owner from dba_extents where block_id=265648;                                            
SEGMENT_NAME                                                                      OWNER
--------------------------------------------------------------------------------- ------------------------------
TEST_ACCOUNT                                                                      N1
可以看到对应的段是一个表,TEST_ACCOUNT
直接做一个move操作看看有没有立竿见影的效果。
> alter tableTEST_ACCOUNT move tablespace example;
Table altered.
但是重新生成resize字句,没有任何变化,还是2G左右。
不能这么被动的处理问题,直接生成了相关的信息。
> select owner,segment_name,segment_type,file_id,max(block_id+blocks-1) HWM,block_id
              from dba_extents
              where file_id=4
              and block_id > 20000
              group by owner,segment_name,segment_type,file_id,block_id;

OWNER  SEGMENT_NAME              SEGMENT_TYPE    FILE_ID        HWM   BLOCK_ID
------ ------------------------- ----------------------- ---------- ----------
N1     TEST_CONSISTENT_GET       TABLE                 4     263831     263824
N1     IDX_TEST_CG               INDEX                 4     263871     263864
N1     IDX_TEST_CG               INDEX                 4     263863     263856
N1     TEST_CONSISTENT_GET       TABLE                 4     263839     263832
N1     TEST_CONSISTENT_GET       TABLE                 4     263847     263840
N1     TEST_CONSISTENT_GET       TABLE                 4     263855     263848

对于表直接使用move操作
>alter table TEST_CONSISTENT_GET move tablespace example;
对于索引直接使用rebuild操作
> alter index IDX_TEST_CG rebuild tablespace example;

这样就把它们给转出去了。这个时候再来看看空间的情况。
> SELECT MAX(block_id)
          FROM dba_extents
         WHERE tablespace_name = 'USERS'; 
MAX(BLOCK_ID)
-------------
          768

> !ls -lrt user*.dbf
-rw-r----- 1 ora11g dba   7348224 May 12 15:07 users01.dbf
生成的resize语句如下:
alter database datafile '/u02/ora11g/oradata/TEST11G/users01.dbf' resize 7M;

从2G到7M,这是多么大的改变,这种收缩文件带来的实惠你值得拥有。

时间: 2024-07-30 05:42:11

关于收缩数据文件的尝试的相关文章

数据库收缩数据文件的尝试(二)(r11笔记第9天)

在之前自己的一个测试环境中,因为本身磁盘空间不足,导致一个测试库数据目录溢出,最后花了点功夫,将一个2G左右的文件经过收缩的操作后,竟然收缩为7M.详情可以参考 收缩关于收缩数据文件的尝试(r5笔记第34天)     而隔了很长一段时间后,我在线上一个环境碰到了类似的问题. 这个数据库是一个OLAP的业务库,之前的数据量还不小,大概有1.7T,但是经过业务梳理之后,有一部分业务不需要的数据就删除了,后续迁移了另外一个环境的数据过来.     从资源的规划来看,这个库的数据增长还远远达不到目前的使

数据库收缩数据文件的尝试(三)(r11笔记第22天)

  不知道大家在数据库运维中是否会有这样的困扰,一个数据文件里没有多少数据,但是数据文件的大小却调不下来,尝试使用resize来调整屡屡失败.如果一个数据文件里有很多的小表,存在大量这样的碎片表,虽然我们从前端看不到,但是如果查看存储结构就会发现还是挺混乱的.     本质上来说,Oracle也不希望我们去刻意处理这些物理存储方面的设置,比如设定某个表一定存放在某个数据文件里,一个表空间里存在10个数据文件,一条insert语句运行下去,到底数据进了哪个数据文件,应该不需要DBA刻意去关心,而且

收缩Oracle数据文件

      最近有网友提到收缩Oracle数据文件的问题,这是DBA经常碰到的一个常见问题.通常我们需要收缩相应的数据文件以减少来自磁盘空间的压力以及提高数据库的整体性能.但这并非对于所有情形都是适用的,尤其是生产环境.因为生产环境数据清洗相当较少,因此空间浪费也比较小,而且一旦收缩之后又要重新自动扩展数据文件,浪费系统资源.对于UAT,DEV环境,多DB,磁盘空间压力大的情形,收缩一下非常有必要.勒紧裤带过日子也是常有的事情,哈哈.总之收缩数据文件会使得磁盘空间得以释放以及加快数据迁移,RMA

[翻译]为什么你不要收缩数据库文件

 我最大的一个热点问题是关于收缩数据文件,虽然在微软的时候,我自己写了相关收缩数据文件代码,我再也没有机会去重写它,让它操作起来更方便.我真的不喜欢收缩.   现在,不要混淆了收缩事务日志文件和收缩数据文件,当事务日志文件的增长失控或为了移除过多的VLF碎片(这里和这里看到金佰利的优秀文章),然而,收缩事务日志数据文件不要频繁使用(罕见的操作)并且不应是你执行定期维护计划的一部分.   收缩数据文件应该执行得甚至更少.这就是为什么--数据文件收缩导致产生了大量索引碎片,让我用一个简单并且你可以运

SQL SERVER中如何手动增长日志文件和数据文件

手动增长日志文件,实际上就是修改日志文件的大小  size 的单位是MB 下面设置日志文件大小是2048MB ALTERDATABASE[GPOSDB] MODIFY FILE(name=GPOSDB_Log,size=2048) EXEC sys.[sp_helpdb] @dbname = [GPOSDB] -- sysname --收缩日志文件 USE [GPOSDB] GO ALTER DATABASE [GPOSDB] SET RECOVERY SIMPLE; GO --设置简单恢复模式

SQLSERVER手动增长日志文件和数据文件

原文:SQLSERVER手动增长日志文件和数据文件 SQLSERVER手动增长日志文件和数据文件 手动增长日志文件,实际上就是修改日志文件的大小  size 的单位是MB 下面设置日志文件大小是2048MB ALTER DATABASE [GPOSDB] MODIFY FILE(name=GPOSDB_Log,size=2048) EXEC sys.[sp_helpdb] @dbname = [GPOSDB] -- sysname --收缩日志文件 USE [GPOSDB] GO ALTER D

[20161101]rman备份与数据文件变化7.txt

[20161101]rman备份与数据文件变化7.txt --//想象一下,如果备份文件时间很长,而这个时候数据文件大小发生了变化,oracle的备份如何解决这个问题呢? --//去年已经测试了建立备份集的情况,一直想做一次image copy的测试,一直脱,主要原因自己不想做这个测试.... --//而且当时的测试很乱,自己主要一边做一边想.... --//链接: http://blog.itpub.net/267265/viewspace-2127386/ http://blog.itpub

tempdb数据文件突然增大的原因

上周公司的生产库的tempdb瞬间暴涨,导致磁盘剩余空间为0,估计是相关人员运行不合理的sql查询导致. tempdb在以下情况会用到: (1)用户建立的临时表.如果能够避免不用,就尽量避免. 如果使用临时表储存大量的数据且频繁访问,考虑添加index以增加查询效率. (2)Schedule jobs.如DBCC CHECKDB会占用系统较多的资源,较多的使用tempdb.最好在SQL Server loading比较轻的时候做. (3)Cursors.游标会严重影响性能应当尽量避免使用. (4

一个数据文件最小能够到多小?

一个数据文件最小能够到多小?以8K block size为例. 在Locally Managed Tablespace(LMT)中,如果是System Allocate的话. 1.LMT的数据文件需要1个block存储datafile header,还需要7个block存储bitmap block,这样是8 个block,一共64K 2.需要保证有至少一个extent的空间,在System Allocate中第一个extent会是64K 因此最小只能到128K.尝试缩小到更小的话,会碰到ORA-