【问题标题】:Oracle Segment Does Not Equal Extents?Oracle 段的范围不相等?
【发布时间】:2021-09-14 19:01:28
【问题描述】:

对于给定的表空间,为什么dba_extents 中的字节总和不等于dba_segments 中的字节总和? (示例脚本后的其他问题。)

SQL> with
  "SEG" as
    ( select 'segment_bytes' what
             , to_char(sum(bytes), '9,999,999,999,999') bytes
        from dba_segments
       where tablespace_name = 'MYDATA'
    )
  , "EXT" as
    ( select 'extent_bytes' what
             , to_char(sum(bytes), '9,999,999,999,999') bytes
        from dba_extents
       where tablespace_name = 'MYDATA'
    )
  , "FS" as
    ( select tablespace_name
             , sum(bytes) free_bytes
        from dba_free_space
       where tablespace_name = 'MYDATA'
       group by tablespace_name
    ),
  "DF" as
    ( select tablespace_name
             , sum(bytes) alloc_bytes
             , sum(user_bytes) user_bytes
        from dba_data_files
       where tablespace_name = 'MYDATA'
       group by tablespace_name
    )
  select what, bytes from SEG
  union all select 'datafile_bytes-freespace' what
                   , to_char(alloc_bytes - nvl(free_bytes, 0), '9,999,999,999,999') used_file_bytes
              from DF
                  left join FS
                         on DF.tablespace_name = FS.tablespace_name
  union all select 'datafile_userbytes-freespace' what
                   , to_char(user_bytes - nvl(free_bytes, 0), '9,999,999,999,999') used_user_bytes
             from DF
                  left join FS
                         on DF.tablespace_name = FS.tablespace_name
  union all select what, bytes from EXT
;
WHAT                         BYTES            
---------------------------- ------------------
segment_bytes                 2,150,514,819,072
datafile_bytes-freespace      2,150,528,540,672
datafile_userbytes-freespace  2,150,412,845,056
extent_bytes                  2,150,412,845,056

4 rows selected.

我希望 segment_bytes 等于 extent_bytes 或 datafile_bytes-freespace,但它介于两者之间。

segment_bytes 是否由于段“开销”(跟踪所有范围)而超过 extent_bytes?

如果是这样,那么这个段“开销”是否也是数据文件“开销”的一部分?

Oracle 19.1 企业版。提前致谢。

【问题讨论】:

    标签: oracle segment tablespace extent


    【解决方案1】:

    例如,dba_segments 和 dba_extents 的区别可能在于 recyclebin 中的对象:请查看我的测试数据库中的结果:

    with 
     seg as (
        select segment_name,sum(bytes) b1 
        from dba_segments 
        group by segment_name
    )
    ,ext as (
        select segment_name,sum(bytes) b2 
        from dba_extents 
        group by segment_name
    )
    select
       seg.segment_name seg1
      ,ext.segment_name seg2
      ,b1,b2
    from seg full outer join ext on seg.segment_name=ext.segment_name
    where lnnvl(b1=b2)
    order by 1,2;
    

    结果:

    SEG1                           SEG2                                   B1         B2
    ------------------------------ ------------------------------ ---------- ----------
    BIN$xi7yNJwFcIrgUwIAFaxDaA==$0                                     65536
    BIN$xi7yNJwGcIrgUwIAFaxDaA==$0                                     65536
    _SYSSMU10_2262159254$          _SYSSMU10_2262159254$                   0    4325376
    _SYSSMU1_3588498444$           _SYSSMU1_3588498444$                    0    3276800
    _SYSSMU2_2971032042$           _SYSSMU2_2971032042$                    0    2228224
    _SYSSMU3_3657342154$           _SYSSMU3_3657342154$                    0    2228224
    _SYSSMU4_811969446$            _SYSSMU4_811969446$                     0    2293760
    _SYSSMU5_3018429039$           _SYSSMU5_3018429039$                    0    3276800
    _SYSSMU6_442110264$            _SYSSMU6_442110264$                     0    2228224
    _SYSSMU7_2728255665$           _SYSSMU7_2728255665$                    0    2097152
    _SYSSMU8_801938064$            _SYSSMU8_801938064$                     0    2228224
    _SYSSMU9_647420285$            _SYSSMU9_647420285$                     0    3276800
    
    12 rows selected.
    

    如您所见,前 2 行是来自回收站的对象,因此您可以运行相同的查询并检查您的对象是否也在回收站中。它们在 dba_extents 中不可见,因为它们被 segment_flag 过滤掉了:

    select text_vc from dba_views where view_name='DBA_EXTENTS';
    
    select ds.owner, ds.segment_name, ds.partition_name, ds.segment_type,
           ds.tablespace_name,
           e.ext#, f.file#, e.block#, e.length * ds.blocksize, e.length, e.file#
    from sys.uet$ e, sys.sys_dba_segs ds, sys.file$ f
    where e.segfile# = ds.relative_fno
      and e.segblock# = ds.header_block
      and e.ts# = ds.tablespace_id
      and e.ts# = f.ts#
      and e.file# = f.relfile#
      and bitand(NVL(ds.segment_flags,0), 1) = 0
      and bitand(NVL(ds.segment_flags,0), 65536) = 0
    union all
    select
           ds.owner, ds.segment_name, ds.partition_name, ds.segment_type,
           ds.tablespace_name,
           e.ktfbueextno, f.file#, e.ktfbuebno,
           e.ktfbueblks * ds.blocksize, e.ktfbueblks, e.ktfbuefno
    from sys.sys_dba_segs ds, sys.x$ktfbue e, sys.file$ f
    where e.ktfbuesegfno = ds.relative_fno
      and e.ktfbuesegbno = ds.header_block
      and e.ktfbuesegtsn = ds.tablespace_id
      and ds.tablespace_id = f.ts#
      and e.ktfbuefno = f.relfile#
      and bitand(NVL(ds.segment_flags, 0), 1) = 1
      and bitand(NVL(ds.segment_flags,0), 65536) = 0;
    

    因此,如果我们注释掉这些谓词 (bitand(NVL(segment_flags,0)....) 并检查我们的区别(BIN$..._SYSSMU... 对象),我们会发现哪些谓词将它们过滤掉:

    with
     my_dba_extents(
       OWNER,SEGMENT_NAME,PARTITION_NAME
      ,SEGMENT_TYPE,TABLESPACE_NAME,EXTENT_ID,FILE_ID
      ,BLOCK_ID,BYTES,BLOCKS,RELATIVE_FNO
      ,segment_flags) 
    as (
    select ds.owner, ds.segment_name, ds.partition_name, ds.segment_type,
           ds.tablespace_name,
           e.ext#, f.file#, e.block#, e.length * ds.blocksize, e.length, e.file#
           ,segment_flags
    from sys.uet$ e, sys.sys_dba_segs ds, sys.file$ f
    where e.segfile# = ds.relative_fno
      and e.segblock# = ds.header_block
      and e.ts# = ds.tablespace_id
      and e.ts# = f.ts#
      and e.file# = f.relfile#
    --  and bitand(NVL(ds.segment_flags,0), 1) = 0
    --  and bitand(NVL(ds.segment_flags,0), 65536) = 0
    union all
    select
           ds.owner, ds.segment_name, ds.partition_name, ds.segment_type,
           ds.tablespace_name,
           e.ktfbueextno, f.file#, e.ktfbuebno,
           e.ktfbueblks * ds.blocksize, e.ktfbueblks, e.ktfbuefno
           ,segment_flags
    from sys.sys_dba_segs ds, sys.x$ktfbue e, sys.file$ f
    where e.ktfbuesegfno = ds.relative_fno
      and e.ktfbuesegbno = ds.header_block
      and e.ktfbuesegtsn = ds.tablespace_id
      and ds.tablespace_id = f.ts#
      and e.ktfbuefno = f.relfile#
    --  and bitand(NVL(ds.segment_flags, 0), 1) = 1
    --  and bitand(NVL(ds.segment_flags,0), 65536) = 0
    )
    select 
       segment_name
      ,bitand(NVL(segment_flags, 0), 1) as predicate_1
      ,bitand(NVL(segment_flags,0), 65536) as predicate_2
      ,case when bitand(NVL(segment_flags,0), 1) = 0     then 'y' else 'n' end pred_1_res
      ,case when bitand(NVL(segment_flags,0), 65536) = 0 then 'y' else 'n' end pred_2_res
    from my_dba_extents e
    where e.segment_name like 'BIN%'
       or e.segment_name like '_SYSSMU%';
    
    SEGMENT_NAME                   PREDICATE_1 PREDICATE_2 PRED_1_RES     PRED_2_RES
    ------------------------------ ----------- ----------- -------------- --------------
    _SYSSMU1_3588498444$                     1           0 n              y
    _SYSSMU1_3588498444$                     1           0 n              y
    _SYSSMU1_3588498444$                     1           0 n              y
    _SYSSMU1_3588498444$                     1           0 n              y
    _SYSSMU1_3588498444$                     1           0 n              y
    _SYSSMU2_2971032042$                     1           0 n              y
    _SYSSMU2_2971032042$                     1           0 n              y
    ...
    _SYSSMU10_2262159254$                    1           0 n              y
    _SYSSMU10_2262159254$                    1           0 n              y
    _SYSSMU10_2262159254$                    1           0 n              y
    BIN$xi7yNJwGcIrgUwIAFaxDaA==$0           1       65536 n              n
    BIN$xi7yNJwFcIrgUwIAFaxDaA==$0           1       65536 n              n
    

    关于“datafile_bytes-freespace”:别忘了每个datafile都有自己的header,所以nor dba_segments,nor dba_extents也不应该算。

    附言。其他 10 行是撤消段,但这不是您的情况,因为您的查询只检查您的 MYDATA 表空间,而不是 UNDO

    【讨论】:

      猜你喜欢
      • 2020-02-02
      • 2022-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-31
      • 2019-11-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多