大家好,有个问题要向各位请教:
一、环境说明
1、系统环境:AIX 5.3
2、Oracle数据库版本:Oracle 10G 10.2.0.1.0 for 64bit AIX5.3
3、Oracle数据库表空间:用的是raw device(裸设备),在应用系统的表空间下建了12个4G的lv(逻辑卷),对应12个Datafiles
4、其他:应用系统已上线但还未正式运行,内无生产数据
二、问题描述:
在做Oracle日常检查时发现,这个应用表空间的下的一个datafile的使用空间为负值-49.75M,我是通过em查看时发现的,后来用Oracle Enterprise Database console查看这个datafile的使用空间,结果也是负值,大小也是-49.75
三、提问;
1、为何?请各位高手指教
2、对数据有无影响?如不处理,以后业务开通了,有了生产数据了,是否有潜在的风险?

解决方案 »

  1.   

    望大家尽快给予答复,如需要重建表空间或删除这个datafile或升级oracle弥补漏动的话,我也好提前做好准备,提前处理,要不上线后再处理就麻烦了,在此对各位表示感谢!
      

  2.   

    SQL> purge recyclebin  然后再看看
      

  3.   

    应该是oracle的一个bug
    你用那个版本?
      

  4.   

    如果真的开通了真实数据,肯定有影响。12个4G的lv(逻辑卷),还不如分成三个逻辑卷,每个卷16G
    空间可考虑每4个用户,使用一个相同的表空间。如不使用归档模式的话,磁盘暂时可以用上一段时间,
    如使用归档模式的话,可考虑新增二块73G或更大一点的硬盘。
      

  5.   

    非常感谢大家的回复,昨日我从网上看到了一位网友的帖子,才知道这个问题确实是Oracle 10G的一个bug。执行下面的命令后,再查看该datafile的使用空间,就正常了。先前在生产系统切换时确实是删除了大量的table和index,而Oracle 10G的回收站功能会将sys、system的drop操作记录在回收站里,而设置的默认大小为2G。当从数据库删除大小超过2G的表时,就有可能会出现表空间里的部分数据文件的使用率为负数。执行的命令:
    $sqlplus "/as sysdba"
    sql> purge dba_recyclebin 
    下面是该网友的贴子,贴出来与大家共享,再次感谢大家的回复。
    第一段:
    (10.2.0.3 RAC)dba_free_space .问一下biti&eygle及各高手. 文件使用率是负数
    现在遇到一个表空间里面的数据文件的使用率问题,想各位高手帮助,了解一下一般的表空间的使用都通过dba_data_files and dba_free_space这两个视图算出来的.现在的问题是
    通过下面的命令得到数据文件的使用率是负,我跟踪了WEB OEM 里的SQL
    使用查询语句也如下面相同,所以很难理解为什么dba_free_space 里的bytes 会比dba_data_files里的bytes大,
    按理说应该是小的,那他们相差就应该是正数.Select ROUND(MAX(d.bytes)/1024/1024,2) "total MB", 
           DECODE(SUM(f.bytes), null, 0, ROUND(SUM(f.Bytes)/1024/1024,2)) "Free MB" , 
           d.file_name "Datafile name",
           DECODE( SUM(f.Bytes), null, 0, ROUND((MAX(d.bytes)/1024/1024) - (SUM(f.bytes)/1024/1024),2)) "Used MB", 
           ROUND(MAX(d.bytes)/1024,2) "total KB", 
           DECODE(SUM(f.bytes), null, 0, ROUND(SUM(f.Bytes)/1024,2)) "Free KB" , 
           DECODE( SUM(f.Bytes), null, 0, ROUND((MAX(d.bytes)/1024) - (SUM(f.bytes)/1024),2)) "Used KB", 
           ROUND(SQRT(MAX(f.BLOCKS)/SUM(f.BLOCKS))*(100/SQRT(SQRT(COUNT(f.BLOCKS)) )), 2) "Fragmentation Index"
    from   DBA_FREE_SPACE f , DBA_DATA_FILES d 
    where  f.tablespace_name(+) = d.tablespace_name 
    and    f.file_id(+) = d.file_id 
    and    d.tablespace_name = :tname 
    and    d.file_name like '/dev/raw/raw73'
    --and    d.file_name like '/dev/raw/raw74'
    group by d.file_name------结果:
    tota MB  |Free MB |Datafile name   |Used MB|total KB  |Free KB  |Used KB|Fragmentation Index
    8000      |8610.69|/dev/raw/raw73|-610.69 |8192000|8817344|-625344|13.87
    通过下面的语句去定位那个数据文件,/dev/raw/raw73,查看此数据文件里的对象;select b.segment_name ,b.BYTES,b.BLOCKS  ,a.BYTES,a.USER_BYTES 
    from dba_data_files a,dba_extents b where a.file_id=b.file_id and a.file_name like '
    /dev/raw/raw73';结果也是有数据的,----这说明此数据文件里的是可以写入数据的,但为什么能过OEM 或是其它工具查得的结果是负使用率呢?
    ---WEB OEM里的查看表空间的SQL ---来自TRACE select  a.tablespace_name,
           round(a.bytes_alloc / 1024 / 1024, 2) megs_alloc,
           round(nvl(b.bytes_free, 0) / 1024 / 1024, 2) megs_free,
           round((a.bytes_alloc - nvl(b.bytes_free, 0)) / 1024 / 1024, 2) megs_used,
           round((nvl(b.bytes_free, 0) / a.bytes_alloc) * 100,2) Pct_Free,
           100 - round((nvl(b.bytes_free, 0) / a.bytes_alloc) * 100,2) Pct_used,
           round(maxbytes/1048576,2) Max
    from  ( select  f.tablespace_name,
                   sum(f.bytes) bytes_alloc,
                   sum(decode(f.autoextensible, 'YES',f.maxbytes,'NO', f.bytes)) maxbytes
            from dba_data_files f
            group by tablespace_name) a,
          ( select  f.tablespace_name,
                   sum(f.bytes)  bytes_free
            from dba_free_space f
            group by tablespace_name) b
    where a.tablespace_name = b.tablespace_name (+)
    union all
    select h.tablespace_name,
           round(sum(h.bytes_free + h.bytes_used) / 1048576, 2) megs_alloc,
           round(sum((h.bytes_free + h.bytes_used) - nvl(p.bytes_used, 0)) / 1048576, 2) megs_free,
           round(sum(nvl(p.bytes_used, 0))/ 1048576, 2) megs_used,
           round((sum((h.bytes_free + h.bytes_used) - nvl(p.bytes_used, 0)) / sum(h.bytes_used + h.bytes_free)) * 100,2) Pct_Free,
           100 - round((sum((h.bytes_free + h.bytes_used) - nvl(p.bytes_used, 0)) / sum(h.bytes_used + h.bytes_free)) * 100,2) pct_used,
           round(f.maxbytes / 1048576, 2) max
    from   sys.v_$TEMP_SPACE_HEADER h, sys.v_$Temp_extent_pool p, dba_temp_files f
    where  p.file_id(+) = h.file_id
    and    p.tablespace_name(+) = h.tablespace_name
    and    f.file_id = h.file_id
    and    f.tablespace_name = h.tablespace_name
    group by h.tablespace_name, f.maxbytes
    ORDER BY 1 ;Select ROUND(MAX(d.bytes)/1024/1024,2) "total MB", 
           DECODE(SUM(f.bytes), null, 0, ROUND(SUM(f.Bytes)/1024/1024,2)) "Free MB" , 
           d.file_name "Datafile name",
           DECODE( SUM(f.Bytes), null, 0, ROUND((MAX(d.bytes)/1024/1024) - (SUM(f.bytes)/1024/1024),2)) "Used MB", 
           ROUND(MAX(d.bytes)/1024,2) "total KB", 
           DECODE(SUM(f.bytes), null, 0, ROUND(SUM(f.Bytes)/1024,2)) "Free KB" , 
           DECODE( SUM(f.Bytes), null, 0, ROUND((MAX(d.bytes)/1024) - (SUM(f.bytes)/1024),2)) "Used KB", 
           ROUND(SQRT(MAX(f.BLOCKS)/SUM(f.BLOCKS))*(100/SQRT(SQRT(COUNT(f.BLOCKS)) )), 2) "Fragmentation Index"
    from   DBA_FREE_SPACE f , DBA_DATA_FILES d 
    where  f.tablespace_name(+) = d.tablespace_name 
    and    f.file_id(+) = d.file_id 
    and    d.tablespace_name = :tname 
    group by d.file_nam;
     问题是:
    1. 数据库里的dba_free_space 里面的bytes是怎样计算的,
    我定义的每个数据文件的大小是8000MB,使用的裸设备.
    EMC的.(型号不清楚)2.数据库里的alert.log里没有相关的错误信息,所以应该很可能是oracle BUG(oracle 工程师说的)
    到目前还没有结果.
      

  6.   

    第二段:
    QUOTE: 
    --------------------------------------------------------------------------------
    原帖由 zluo 于 2008-1-18 01:08 发表 
    ...
    使用查询语句也如下面相同,所以很难理解为什么dba_free_space 里的bytes 会比dba_data_files里的bytes大,
    按理说应该是小的,那他们相差就应该是正数.Select ROUND(MAX(d.bytes)/1024/1024,2) "total MB", 
           DECODE(SUM(f.bytes), null, 0, ROUND(SUM(f.Bytes)/1024/1024,2)) "Free MB" , 
           d.file_name "Datafile name",
           DECODE( SUM(f.Bytes), null, 0, ROUND((MAX(d.bytes)/1024/1024) - (SUM(f.bytes)/1024/1024),2)) "Used MB", 
           ROUND(MAX(d.bytes)/1024,2) "total KB", 
           DECODE(SUM(f.bytes), null, 0, ROUND(SUM(f.Bytes)/1024,2)) "Free KB" , 
           DECODE( SUM(f.Bytes), null, 0, ROUND((MAX(d.bytes)/1024) - (SUM(f.bytes)/1024),2)) "Used KB", 
           ROUND(SQRT(MAX(f.BLOCKS)/SUM(f.BLOCKS))*(100/SQRT(SQRT(COUNT(f.BLOCKS)) )), 2) "Fragmentation Index"
    from   DBA_FREE_SPACE f , DBA_DATA_FILES d 
    where  f.tablespace_name(+) = d.tablespace_name 
    and    f.file_id(+) = d.file_id 
    and    d.tablespace_name = :tname 
    and    d.file_name like '/dev/raw/raw73'
    --and    d.file_name like '/dev/raw/raw74'
    group by d.file_name------结果:
    tota MB  |Free MB |Datafile name   |Used MB|total KB  |Free KB  |Used KB|Fragmentation Index
    8000      |8610.69|/dev/raw/raw73|-610.69 |8192000|8817344|-625344|13.87
    ... 
    --------------------------------------------------------------------------------
    https://metalink.oracle.com/metalink/plsql/ml2_documents.showDocument?p_database_id=NOT&p_id=444170.1saysWorkaround :
    -------------
    Purge all objects from the recycle bin.$sqlplus "/as sysdba"
    sql> purge dba_recyclebin Yong Huang
      

  7.   

    第三段:谢谢您的帮助!那个问题前天就解决了,与您给的方法一样的,过几天把相关的解决方法和大家说一下.有一个思考:如果这样表空间里面的数据使用计算错误会不会引起其它问题?
    我还没有搞清楚!数据库里的数据文件使用率显示为负数(解决办法)主题:当在数据库里删除大量数据时,当删除的数据量大于2G后,数据库里OEM里显示的文件的使用率为负数.
    dba_data_files.bytes - dba_free_space.bytes_free
    -----这个计算数为负数了.
    那根据如下的SQL进行检查时,出现的结果表空间里的部分的数据文件的使用率为负数.
    ----以下的SQL是WEB OEM trace 文件里的.
    select  a.tablespace_name,
           round(a.bytes_alloc / 1024 / 1024, 2) megs_alloc,
           round(nvl(b.bytes_free, 0) / 1024 / 1024, 2) megs_free,
           round((a.bytes_alloc - nvl(b.bytes_free, 0)) / 1024 / 1024, 2) megs_used,
           round((nvl(b.bytes_free, 0) / a.bytes_alloc) * 100,2) Pct_Free,
           100 - round((nvl(b.bytes_free, 0) / a.bytes_alloc) * 100,2) Pct_used,
           round(maxbytes/1048576,2) Max
    from  ( select  f.tablespace_name,
                   sum(f.bytes) bytes_alloc,
                   sum(decode(f.autoextensible, 'YES',f.maxbytes,'NO', f.bytes)) maxbytes
            from dba_data_files f
            group by tablespace_name) a,
          ( select  f.tablespace_name,
                   sum(f.bytes)  bytes_free
            from dba_free_space f
            group by tablespace_name) b
    where a.tablespace_name = b.tablespace_name (+)
    union all
    select h.tablespace_name,
           round(sum(h.bytes_free + h.bytes_used) / 1048576, 2) megs_alloc,
           round(sum((h.bytes_free + h.bytes_used) - nvl(p.bytes_used, 0)) / 1048576, 2) megs_free,
           round(sum(nvl(p.bytes_used, 0))/ 1048576, 2) megs_used,
           round((sum((h.bytes_free + h.bytes_used) - nvl(p.bytes_used, 0)) / sum(h.bytes_used + h.bytes_free)) * 100,2) Pct_Free,
           100 - round((sum((h.bytes_free + h.bytes_used) - nvl(p.bytes_used, 0)) / sum(h.bytes_used + h.bytes_free)) * 100,2) pct_used,
           round(f.maxbytes / 1048576, 2) max
    from   sys.v_$TEMP_SPACE_HEADER h, sys.v_$Temp_extent_pool p, dba_temp_files f
    where  p.file_id(+) = h.file_id
    and    p.tablespace_name(+) = h.tablespace_name
    and    f.file_id = h.file_id
    and    f.tablespace_name = h.tablespace_name
    group by h.tablespace_name, f.maxbytes
    ORDER BY 1 
    ------
    Select ROUND(MAX(d.bytes)/1024/1024,2) "total MB", 
           DECODE(SUM(f.bytes), null, 0, ROUND(SUM(f.Bytes)/1024/1024,2)) "Free MB" , 
           d.file_name "Datafile name",
           DECODE( SUM(f.Bytes), null, 0, ROUND((MAX(d.bytes)/1024/1024) - (SUM(f.bytes)/1024/1024),2)) "Used MB", 
           ROUND(MAX(d.bytes)/1024,2) "total KB", 
           DECODE(SUM(f.bytes), null, 0, ROUND(SUM(f.Bytes)/1024,2)) "Free KB" , 
           DECODE( SUM(f.Bytes), null, 0, ROUND((MAX(d.bytes)/1024) - (SUM(f.bytes)/1024),2)) "Used KB", 
           ROUND(SQRT(MAX(f.BLOCKS)/SUM(f.BLOCKS))*(100/SQRT(SQRT(COUNT(f.BLOCKS)) )), 2) "Fragmentation Index"
    from   DBA_FREE_SPACE f , DBA_DATA_FILES d 
    where  f.tablespace_name(+) = d.tablespace_name 
    and    f.file_id(+) = d.file_id 
    and    d.tablespace_name = :tname 
    group by d.file_name ------这个SQL是检查某个数据文件里的存储了对象.
    select b.segment_name ,b.BYTES,b.BLOCKS  ,a.BYTES,a.USER_BYTES 
    from dba_data_files a,dba_extents b where a.file_id=b.file_id and a.file_name like 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\USERS01.DBF'是先创建 然后 alter table allocate datafile '/u01/user01.dbf' 
    alter table  tablename ALLOCATE EXTENT  DATAFILE 'filename';================================
    此问题解决办法:----设想:
    因为oracle 10g 里设有回收站功能,它能记录非常SYS,SYSTEM的drop操作.
    而设置的大小为:2G(设想)
    会记录到dba_recyclebin/user_recyclebin/recyclebin----测试现象:
    当从数据库里删除大于2G的表时(没有增加purge参数),那就回出现表空间里的部分数据文件的使用率为负数.----解决办法 :
    1. 增大db_file_recovery_file_dest_size 2G的大小,(如果没有在安装时设置大小,那显示数为0)
    若没有在安装时设置,那数据库里默认设置还是2G,当在删除(drop操作时),数据库会使用该用户的表空间来保存DROP可恢复数据,
    用表空间的一定空间来保存.(注意:表空间的变化量)2.删除数据库里的dba_recyclebin/user_recyclebin/recyclebin里面的记录,那OEM就能正常显示.================================
    疑问:如果有OEM出现这样的数据文件使用率为负数的问题,
    那oracle 怎样再去使用与计算表空间的使用呢?如果不能正确解决这个问题,那日后再继续时,很可以会出错误,会导致数据库不能正常使用,
    所以认为,这是数据库的一个BUG,需要oracle 更改这一计算方式或过程,就此问题还在进一步去研究.
    Bug 5083393支持一个。楼主分析和总结的非常好。支持楼主共享。