Сегмент Oracle Не Равен Экстентам?

#oracle #segment #tablespace #extent

Вопрос:

Для данного табличного пространства, почему 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-свободное пространство, но оно находится где-то посередине.

Является ли segment_bytes больше, чем extent_bytes, из-за «накладных расходов» сегмента (отслеживание всех экстентов)?

Если да, то верно ли также, что этот сегмент «накладные расходы» является частью «накладных расходов»файла данных?

Oracle 19.1 Enterprise Edition. Заранее спасибо.

Ответ №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 строки являются объектами из recyclebin, поэтому вы можете выполнить тот же запрос и проверить, находятся ли ваши объекты тоже в recyclebin. Они не видны в 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
 

Re «datafile_bytes-свободное пространство»: Не забывайте, что каждый файл данных имеет собственный заголовок, поэтому ни dba_segments, ни dba_extents не должны его учитывать.

PS. Остальные 10 строк являются сегментами отмены, но это не ваш случай, так как ваш запрос проверяет только ваше MYDATA табличное пространство, а не UNDO .