Oracle 段不等于范围?
Oracle Segment Does Not Equal Extents?
对于给定的表空间,为什么 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?
如果是这样,那么这个段“overhead”是否也是数据文件“overhead”的一部分?
甲骨文19.1企业版。提前致谢。
例如dba_segments和dba_extents之间的区别可能在objects来自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==[=11=] 65536
BIN$xi7yNJwGcIrgUwIAFaxDaA==[=11=] 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.
如您所见,前两行 objects 来自回收站,因此您可以 运行 相同的查询并检查您的 objects 是否也在回收站中。它们在 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...
objects),我们会发现哪些谓词过滤掉了它们:
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==[=13=] 1 65536 n n
BIN$xi7yNJwFcIrgUwIAFaxDaA==[=13=] 1 65536 n n
回复“datafile_bytes-freespace”:不要忘记每个数据文件都有自己的header,所以dba_segments,dba_extents也不应该算它。
PS。其他 10 行是撤消段,但这不是你的情况,因为你的查询只检查你的 MYDATA
表空间,而不是 UNDO
.
对于给定的表空间,为什么 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?
如果是这样,那么这个段“overhead”是否也是数据文件“overhead”的一部分?
甲骨文19.1企业版。提前致谢。
例如dba_segments和dba_extents之间的区别可能在objects来自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==[=11=] 65536
BIN$xi7yNJwGcIrgUwIAFaxDaA==[=11=] 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.
如您所见,前两行 objects 来自回收站,因此您可以 运行 相同的查询并检查您的 objects 是否也在回收站中。它们在 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...
objects),我们会发现哪些谓词过滤掉了它们:
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==[=13=] 1 65536 n n
BIN$xi7yNJwFcIrgUwIAFaxDaA==[=13=] 1 65536 n n
回复“datafile_bytes-freespace”:不要忘记每个数据文件都有自己的header,所以dba_segments,dba_extents也不应该算它。
PS。其他 10 行是撤消段,但这不是你的情况,因为你的查询只检查你的 MYDATA
表空间,而不是 UNDO
.