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

在之前自己的一个测试环境中,因为本身磁盘空间不足,导致一个测试库数据目录溢出,最后花了点功夫,将一个2G左右的文件经过收缩的操作后,竟然收缩为7M。详情可以参考 收缩关于收缩数据文件的尝试(r5笔记第34天)

    而隔了很长一段时间后,我在线上一个环境碰到了类似的问题。

这个数据库是一个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
-------------------- --- - - ---- ------------ ---------- -----------
AUDIT_TAB            OLN L S  64K            3          1           2
CMBI_MIN_DATA        OLN L S  64K    1,183,573    847,492     336,081
CMBI_MIN_INDEX       OLN L S  64K      269,454    221,167      48,287
SYSAUX               OLN L S  64K          870         68         802
SYSTEM               OLN L S  64K          700        374         326
TEMP                 OLN L U   1M       63,487     63,487           0
UNDOTBS1             OLN L S  64K       38,304     26,206      12,098
USERS                OLN L S  64K          204         11         193
                                  ------------ ---------- -----------
sum                                  1,556,594  1,158,805     397,790

所以这种情况需要改善,但是收起来容易,做起来难。

因为我很快发现问题比我想的要复杂一些。大体来说数据文件的高水线县问题有三类。

在数据文件的起始位置附近。

或者是中间的位置

在数据文件的中间出现较大的断层。


或者是末尾附近的位置。

总之,这些位置都有可能出现大量的碎片,使用脚本查看可以收缩的空间,竟然只能省出18M左右的空间。

     FILE#  CURRENTMB   RESIZETO  RELEASEMB RESIZECMD
---------- ---------- ---------- ---------- --------------------------------------------------------------------------------
        37 32767.9844 32748.9922 18.9921875 alter database datafile '/U01/app/oracle/oradata/tlbb3dbidb/cmbi_min_data21.dbf' resize 32749M;

所以这问题还是蛮纠结的。查看数据文件的高水线,对应的脚本如下:

sqlplus -s / as sysdba <<EOF
set linesize 200
col segment_name format a35
col segment_type format a15
col tablespace_name format a20
col file_name format a60
col partition_name format a20
set pages 50
select tablespace_name,file_name,bytes/1024/1024 size_MB from dba_data_files where file_id=$1;
select * from (select file_id,segment_name,partition_name,segment_type,max(block_id+blocks-1) HWM,block_id
             from dba_extents
             where file_id=$1
             group by file_id,block_id, segment_name,partition_name,segment_type order by hwm ) where rownum <decode('$2',null,5000,'$2');

col name format a30
col ResizeCMD format a80
set pages 100
select a.file#,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.file#=$1
   and (a.bytes - HWM *block_size)>0 order by ReleaseMB;
EOF 只需要输入数据文件的id即可。

怎么尽可能全面,快捷的降低高水位线呢,一种方式就是在当前的数据文件中寻找那些空间使用出入较大的对象。

还有一种思路也算比较简单,就是新建一个表空间,然后把数据都迁移到这个表空间。

而通用的思路为了达到高可用性,可以使用在线重定义,或者是基于ROWID的方式来删除,插入数据,因为开启的事务级支持,所以依旧可以,而且操作起来也会有一些思路和方法可以参考。

时间: 2024-07-30 05:39:44

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

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

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

关于收缩数据文件的尝试

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

Sql数据库MDF数据文件数据库恢复

EXEC sp_attach_db @dbname = 'dbname', @filename1 = 'd:\dbname_Data.MDF', @filename2 = 'd:\dbname_log.ldf'  sp_attach_single_file_db @dbname = 'dbname' , @physname = 'physical_name' dbname:即要还原的数据库名字. Physname:即物理文件名. Physical_name:即.mdf文件路径. 数据库 : ms

假期前的数据库检查脚本之主备关系(r11笔记第46天)

   快过年了,很多系统都要进入最后的检查和复验阶段,一方面在节假日前,提前发现问题总比过节的时候发现要好.另一方面如果出现故障的时候能及时进行处理,这个时候我们就需要有一个尽可能全面的元数据收集.而且还有一点比较重要的就是工作交接,如果你临时有事,需要让同事来代劳,你得提供清晰易懂的信息给他们.    可能有的同学会觉得我们已经有了数据库监控,基本的性能分析,这个工作是不是就可以忽略了.监控只是标记状态,出现问题时候它没法帮你处理,还是需要人工介入,而人工介入尽可能全面的信息就是这些元数据了,

收缩Oracle数据文件

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

Oracle某个数据文件损坏,如何打开数据库

oracle|数据|数据库 某个数据文件损坏,如何打开数据库? 系统环境: 1.操作系统:Windows 2000 Server,机器内存128M2.数据库: Oracle 8i R2 (8.1.6) for NT 企业版3.安装路径:C:\ORACLE 错误现象: 因误操作,数据库中某一数据文件被误删,控制面板的Oracle相关服务显示已启动,但用SQL*Plus无法连接,显示以下错误ORA-01033: ORACLE initialization or shutdown in progres

如何从完好的数据文件恢复oracle数据库

一.有数据文件.控制文件和日志文件的备份1.服务器重装了操作系统,oracle也重装了.如果重装的oracle和以前损坏的数据库是一模一样的结构,那么此时的恢复是比较简单的. 1)删除掉新建数据库的所有数据文件.控制文件和日志文件.Copy原数据库的数据文件.控制文件和日志文件到对应目录下. 2) Cmd>sqlplus /nolog Sql>conn as sysdba 用户名:system 密码:(此处密码为新创建数据库的密码) Sql>shutdown immediate Sql&

Oracle的数据库、表空间及数据文件简介

数据文件是数据库的物理存储单位,而表空间TableSpace则是数据库的逻辑组成部分.数据库的数据是存储在表空间中的,而一个表空间可以由一个或多个数据文件组成,一个数据文件只能属于一个表空间.一旦数据文件被加入到某个表空间后,就不能删除这个文件,如果要删除某个数据文件,只能删除其所属于的表空间才行. 数据库,表空间,数据文件是紧密关联的,但它们有着重要的区别: 数据库和表空间 一个Oracle数据库由一个或多个叫做表空间的逻辑存储单元组成,表空间存储了所有数据库的数据. 表空间和数据文件 在Or

oracle物理结构(二)数据文件

数据文件(数据文件的详细信息记载在控制文件中) ·每个oracle数据库必须至少有一个数据文件,用于存放数据库数据 ·多个数据文件应分放在不同的disk上以提高存取速度 1.主要分类: system01.dbf:记录系统运行信息,包含所有数据库字典,PL/SQL程序代码及其他系统信息 undotbs01.dbf:存放回退信息,即DML操作后的旧数据信息 sysaux01.dbf:system文件的辅助文件,存放支持oracle系统活动的多种工具如logminer users01.dbf:新建用户