为提高效率,提问时请提供以下信息,问题描述清晰可优先响应。
【DM版本】: v8
【操作系统】:kylin v10
【CPU】:
【问题描述】*创建一个表,查看segments,extents,对应的数据页,在extents中显示有2个blocks,在segment中显示96个blocks,在segment中看到extents有两个,在extents中只看到一个。
:18:51:06 yincq_yincq@yincqnynkc.awr> 18:51:06 yincq_yincq@yincqnynkc.awr> SELECT * FROM SYS.DBA_EXTENTS where OWNER='YINCQ' AND segment_name = 'TEST_BTREE01';
行号 OWNER SEGMENT_NAME PARTITION_NAME SEGMENT_TYPE TABLESPACE_NAME EXTENT_ID FILE_ID BLOCK_ID BLOCKS BYTES RELATIVE_FNO
1 YINCQ TEST_BTREE01 NULL TABLE TEST2025 3 0 96 2 65536 0
1 rows got
18:51:14 yincq_yincq@yincqnynkc.awr> select * from sys.dba_segments where OWNER='YINCQ' AND segment_name = 'TEST_BTREE01';
行号 OWNER SEGMENT_NAME PARTITION_NAME SEGMENT_TYPE SEGMENT_SUBTYPE TABLESPACE_NAME HEADER_FILE HEADER_BLOCK BYTES BLOCKS EXTENTS INITIAL_EXTENT NEXT_EXTENT MIN_EXTENTS MAX_EXTENTS MAX_SIZE RETENTION MINRETENTION PCT_INCREASE FREELISTS FREELIST_GROUPS RELATIVE_FNO BUFFER_POOL FLASH_CACHE CELL_FLASH_CACHE
1 YINCQ TEST_BTREE01 NULL TABLE NULL TEST2025 0 96 2097152 64 2 1048576 1048576 1 2147483645 2147483645 NULL NULL NULL NULL NULL 0 DEFAULT NULL NULL
1 rows got
18:51:31 yincq_yincq@yincqnynkc.awr>
我认同一楼的观点。这是我昨做《为什么dba_sgements记录的bytes比dba_extents大一些?》做的一个测试,希望能帮到你理解:
这需要从DM8的存储结构、段分配机制和最小分配单位说起,DM最小数据存储单位为页,默认大小为 8KB,一旦创建好了数据库,则在该库的整个生命周期内,页大小都不能够改变。
以簇数32,页大小32KB举例,
创建一个对象如果是段立即分配,会立即分配一个簇(连续的32个数据页给到这个段)给到这个对象,然而这些簇并不会一下全部分配,也不能被其它对象使用,因为系统无法判断创建表的大小(Oracle提供了统一管理区大小的方式自定义初始区大小)
下一级分配单位簇,在Oracle也叫区也有自己的分配方式,它使用最小存储单元页作为分配方式,第一次最少分配2个页,根节点和叶子节点。
-- 删除test测试表
drop table test;
--创建测试表
create table test as select * from dba_objects where 1=2;
--插入数据并提交
insert into test value (select * from dba_objects);
commit;
select * from dba_segments where segment_name='TEST';
select * from DBA_EXTENTS where segment_name='TEST';
通过查看dba_extents得知TEST表分配了15个blocks(页),共1532K1024=49152 bytes。
而dba_sgements记录的是对象所有段的分配情况,一个表段最大簇数32*页大小32KB/1024=1MB,和上面查出来的大小一致,这和操作系统一次IO大小也是非常匹配的。值得一提的是,操作系统磁盘读数据页是以页为单位的,也就是说即使只读表中的一行数据,也会将整个数据页读到缓存中。
综上,DBA_EXTENT只记录对象当前已分配并使用的簇(extent),而 DBA_SEGMENTS 则记录整个段(segment)的预分配上限或可用簇空间,自然比DBA_EXTEN大一些
dmdba@DAMENG:5236 SQL> select SF_GET_EXTENT_SIZE() size;
SIZE
-----------
32
dmdba@DAMENG:5236 SQL> SELECT SF_GET_PAGE_SIZE()/1024 KB;
KB
--
32

这个我觉得可以这样理解
从 DBA_EXTENTS 中查询得到的BLOCKS,是目前该表对象在数据库中实际记录数据所占用的数据页数量
而从 DBA_SEGMENTS 中查询得到的是目前已经为该数据表对象分配的数据页数量
在DM中,每次给表分配空间是以区为单位的,可以用 SF_GET_EXTENT_SIZE 函数得到一个区的数据页数量设置值
比如,目前设置的 EXTENT_SIZE 是16,也就是一个区是16个数据页,那在创建表时,初始就会分配16个连续数据页,然后向其中开始写入数据
写入的数据,最开始记录少的时候就是一个叶子节点页,然后应该有一个跟当前表附属的控制信息页(貌似用来存counter啥的)。所以是两个页
我理解大概是这样,但具体咋弄的就不知道了。。。