ITPub博客

首页 > Linux操作系统 > Linux操作系统 > Oracle磁盘碎片处理三阶段与表空间迁移

Oracle磁盘碎片处理三阶段与表空间迁移

原创 Linux操作系统 作者:无名雪狼 时间:2011-04-09 13:41:12 0 删除 编辑

Oracle磁盘碎片处理三阶段与表空间迁移

       在数据库创建之后,磁盘的空间是连续的,但是随着对数据的DML操作,在数据库的数据块中就会出现一些磁盘碎片。磁盘碎片会影响磁盘I/O操作,浪费磁盘空间,就拿链化现象来说吧,通常链化行都会跨越不止一个数据块,所以当读取链化行时,所需要的磁盘I/O就需要读取不止一个数据块,从而增大了磁盘I/O操作,影响数据库性能。
    对于数据库的磁盘碎片处理,可以总结为三个处理阶段:预防、监控、清理。

   
第一阶段:预防
       
对于磁盘碎片的预防阶段,主要是在对数据库、表空间或表的设计是所作的一些操作。对于表空间的设计,在设计时,如果可以预测表空间的段将会增大到多大的尺寸,那么最好使用同一的盘区分配,而不是使用自动的盘区分配。并且在确定数据库块大小的时候,将数据库块大小指定为操作系统块大小的倍数,这有利于磁盘的I/O操作,同时指定表空间的盘区大小为数据库块大小的倍数,这样在盘区中就可以存放刚好的整数个数据库块,而不会因为盘区剩余空间的大小不能放下一个数据库块而纠结。最好是使用ASSM来管理表空间,因为这可以减少管理员的工作,而且这也可以减少空闲列表的使用而带来的性能影响,比如空闲列表的争用。
       
而且,在指定表空间盘区大小的时候,如果可以的话,先预测一下段的大小,对于盘区过多的段,可以将盘区尺寸设计的大一点以适合于段,一个太多盘区的段的性能要比一个有适当盘区大小和盘区数量的段的性能要低。
      
除此之外,链化现象也会导致磁盘碎片,链化现象的出现是因为磁盘的数据块中没有足够的空间用以存储DML操作对表中行的更改,当在磁盘数据块中的空闲空间不足时,被更改的行就会链接到另外的数据块以存储信息,就这样,链化行就产生了。链化行会极大的降低数据库的性能,降低磁盘I/O性能,从未降低了对数据的查询性能,而且带了了磁盘碎片。要预防链化带来的磁盘碎片,那么,在设计表的时候,就应该正确的预测数据块的空闲空间,以适应数据块中的行的更改或增长,在默认情况下空闲空间是数据块的10%,但是,如果表的DML操作非常频繁,那么或许就需要更大的空闲空间了,但是如果是只读块,则需要更少的空闲空间。

   
第二阶段:监控
       
就算在磁盘碎片的预防阶段做的多么的好,我想谁也不能绝对的保证你的磁盘就不会出现或极少出现磁盘碎片吧,就像有些DBA所担忧的一样,谁也不想在梦中做着白马王子的时候,现实中的灾难却悄悄降临。
       
所以定时的监控是很有必要的,虽然我没有尝试过半夜接到客户投诉的电话,但是听起来那是一件糟糕的事情。
       
对表空间的碎片的监控可以用自由空间碎片索引值来显示,也就是通常所说的FSFI值:
   
FSFI=100*SQRT(max(extent)/sum (extents))*1/SQRT(SQRT(count(extents)))
         
通过查找就算FSFI值就可以知道碎片的产生。而且对于链化现象,可以通过查看statspack报表或awr报表的fetch by continued row的值,或者是通过查看v$sysstattable fetch continued row的值,如果有链化行就会有值。

    
第三阶段:清理
       
如果在磁盘中出现了严重的磁盘碎片化现象,那么接下来的工作应该是处理磁盘碎片,从而挺高磁盘I/O性能和节省空间。
       
在有一天我发现我的磁盘出现了大量的磁盘碎片,但是当进一步查看是发现出现磁盘碎片的是其中的一张表。这时我就可以针对这一张表来处理磁盘碎片,首先我选择的方法是使用CTAS方法来创建一张表,原来的表是book,所以可以使

CTAS先创建一张表book1
            
Create table book1
                 As
                
Select * from book
                 
Nologging;
使用nologging子句可以在创建book1是不产生日志信息,从而可以加快创建速度。创建好book1后接下来就是删除book表,删除之后再重名民book1book
            
Alter table rename book1 to book
除了使用CTAS方法,可以用另外一种方法,就是使用expdpimpdp导入/导出表的方法,而且这样好像比使用CTAS方法要更快一点,但是必须保证在导出完表然后删除数据库中的表之后、导入表之前,导出文件是健康的。
      
但是在我的另外一次发现中,我发现磁盘碎片并不是在某个表的数据块上,而是在表空间中的很多数据文件的磁盘中都有挺多的磁盘碎片,所以这时就需要对整个表空间进行碎片处理,我使用的方法是使用expdpimpdp数据泵进行表空间的导出/导入。
      
此方法为四步骤:导出表空间、删除表空间、创建表空间、导入表空间
        第一步:使用expdp将表空间导出:
                Expdp bookinfo/password
                datafile=dir1:tbs_book_01.dmp
                logfile=dir2:tbs_book_exp_logfile_01.log
                tablespaces=tbs_book
          
第二步:删除被导出的表空间
           (如果表空间中存储了其他表空间的表分区,需
             先将分区移动打其他表空间。而且不能删除默
             认的表空间)
                Drop tablespace tbs_book including 
                      contentsand datafiles;
          
第三步:创建一个同名的表空间
           
Create tablespace tbs_book
             
   Datafile ‘/u01/oradata/db1/tbs_book_01.
                            dbf’ size 45M autoextend on
                            next 5M maxsize 200M
                
Extent management local
                    Segment space management auto

                 Blocksize 8k;
          
第四步:导入表空间
            
Impdp bookinfo/password
                datafile=dir1:tbs_book_01.dmp
                logfile=dir2:tbs_book_imp_logfile_01.log
                tablespaces=tbs_book

如果这一切对你来说都还不够,其实重建数据库也是一种方法,不过这将耗费大量的时间和系统性能,而且不会带来太多的性能改善,据说很有风险,但至少我没有试过,尽管是在实验环境上。

 

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/25244847/viewspace-692017/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2011-01-14

  • 博文量
    9
  • 访问量
    31211