表空间和数据文件 实验一:本地管理表空间LMT
本地管理表空间是在每个表空间的数据文件的头部加入了一个位图区域,其中记录了每个区间的使用情况。此实验通过分析跟踪文件,发现分配和删除后区间的变化规律,理解本地管理表空间的原理,主要用到的视图是dba_extents 。
一. 登录系统,查看dba_extents
SQL*Plus: Release 10.2.0.1.0 - Production on 星期三 12月 22 14:59:30 2010
Copyright (c) 1982, 2005, Oracle. All rights reserved.
SQL> conn system/m1234 as sysdba;
已连接。
SQL> desc dba_extents;
名称 是否为空? 类型
----------------------------------------- -------- ----------------------------
OWNER VARCHAR2(30)
SEGMENT_NAME VARCHAR2(81)
PARTITION_NAME VARCHAR2(30)
SEGMENT_TYPE VARCHAR2(18)
TABLESPACE_NAME VARCHAR2(30)
EXTENT_ID NUMBER
FILE_ID NUMBER
BLOCK_ID NUMBER
BYTES NUMBER
BLOCKS NUMBER
RELATIVE_FNO NUMBER
SQL> select tablespace_name,min_extents,max_extents,segment_space_management from dba_tablespaces;
TABLESPACE_NAME MIN_EXTENTS MAX_EXTENTS SEGMEN
------------------------------ ----------- ----------- ------
SYSTEM 1 2147483645 MANUAL
UNDOTBS1 1 2147483645 MANUAL
SYSAUX 1 2147483645 AUTO
TEMP 1 MANUAL
USERS 1 2147483645 AUTO
EXAMPLE 1 2147483645 AUTO
PERFSTAT 1 2147483645 AUTO
已选择7行。
二.分配空间,看位图变化
SQL> set linesize 500;
SQL> select extent_id,block_id,blocks from dba_extents where segment_name='EMP1' and tablespace_name='USERS';
EXTENT_ID BLOCK_ID BLOCKS
---------- ---------- ----------
0 529 8
SQL> select file_id,block_id,blocks from dba_extents where segment_name='EMP1';
FILE_ID BLOCK_ID BLOCKS
---------- ---------- ----------
4 529 8
注意:以下跟踪的都是文件的1到3块,看的是第3块信息。也可以直接跟踪第3块。
SQL> alter system dump datafile 4 block min 1 block max 3;
系统已更改。
对文件的前3个块进行跟踪,发现第1,2块都是记录文件头信息,第3块才开始记录位图信息,以下为第3块的信息:
RelFno: 4, BeginBlock: 9, Flag: 0, First: 4, Free: 63421
FFFFFFFFFFFFFFFF 0B00000000000000 0000000000000000 0000000000000000
再分配一个区间,看情况有什么变化?
SQL> alter table scott.emp1 allocate extent;
表已更改。
SQL> select file_id,extent_id,block_id,blocks from dba_extents
2 where segment_name='EMP1' ;
FILE_ID EXTENT_ID BLOCK_ID BLOCKS
---------- ---------- ---------- ----------
4 0 529 8
4 1 537 8
可以发现,增加了一个区间,这个区间有8个块;BLOCK_ID为537,共8个块。
SQL> alter system dump datafile 4 block min 1 block max 3;
系统已更改。
RelFno: 4, BeginBlock: 9, Flag: 0, First: 67, Free: 63420
FFFFFFFFFFFFFFFF 0F00000000000000 0000000000000000 0000000000000000
与前一个跟踪对比:
RelFno: 4, BeginBlock: 9, Flag: 0, First: 4, Free: 63421
FFFFFFFFFFFFFFFF 0B00000000000000 0000000000000000 0000000000000000
B=1011 转换 1101 0000
F=1111转换 1111 0000 ,说明增加了一位,也就是说一个区间被用了。
Free也减小了1个,由63421变为63420
创建一个新表,并联系分配3个区间:
SQL> create table scott.emp5 as select * from scott.emp;
表已创建。
SQL> alter table scott.emp5 allocate extent;
表已更改。
SQL> /
表已更改。
SQL> /
表已更改。
alter system dump datafile 4 block min 1 block max 3;
RelFno: 4, BeginBlock: 9, Flag: 0, First: 72, Free: 63416
FFFFFFFFFFFFFFFF FF00000000000000 0000000000000000 0000000000000000
上次的为:
RelFno: 4, BeginBlock: 9, Flag: 0, First: 67, Free: 63420
FFFFFFFFFFFFFFFF 0F00000000000000 0000000000000000 0000000000000000
因为增加了4个区间,所以由0F变为FF。同时也由昨日的Free: 63420变为Free: 63416。但First 这项是不是起始位置,怎么开始时是First: 4,增加了一个区后变为First: 67,增加了4个区间后变为First: 72? 这个是这样的:开始时First不在EMP1表的块位置,增加一个区间后跳到EMP1的块这个位置,EMP1块的变化位置就是67,等增加了4个区间后变为First: 72,因为EMP1到EMP5中间还有一个EMP4,这个也占了一个区间,所以是跳了5下,而不是4下。请看下面:
SQL> select file_id,extent_id,block_id,blocks from dba_extents
2 where segment_name='EMP1' ;
FILE_ID EXTENT_ID BLOCK_ID BLOCKS
---------- ---------- ---------- ----------
4 0 529 8
4 1 537 8
SQL> select file_id,extent_id,block_id,blocks from dba_extents
2 where segment_name='EMP5';
FILE_ID EXTENT_ID BLOCK_ID BLOCKS
---------- ---------- ---------- ----------
4 0 553 8
4 1 561 8
4 2 569 8
4 3 577 8
SQL> select file_id,extent_id,block_id,blocks from dba_extents where file_id=4 order by block_id;
FILE_ID EXTENT_ID BLOCK_ID BLOCKS
4 0 521 8
4 0 529 8
4 1 537 8
4 0 545 8 这个块是哪里的?
4 0 553 8
4 1 561 8
4 2 569 8
4 3 577 8
SQL> select * from dba_extents where block_id=545 and file_id=4;
OWNER SEGMENT_NAME
------------------------------ -------------------------------------
SCOTT EMP4
SQL> select file_id,extent_id,block_id,blocks from dba_extents
2 where segment_name='EMP4';
FILE_ID EXTENT_ID BLOCK_ID BLOCKS
---------- ---------- ---------- ----------
4 0 545 8
用EMP5同样的方式增加EMP6表空间:
SQL> create table scott.emp6 as select * from scott.emp;
表已创建。
SQL> alter table scott.emp6 allocate extent;
表已更改。
SQL> /
表已更改。
SQL> /
表已更改。
SQL> select file_id,extent_id,block_id,blocks from dba_extents
2 where segment_name='EMP6';
FILE_ID EXTENT_ID BLOCK_ID BLOCKS
---------- ---------- ---------- ----------
4 0 585 8
4 1 593 8
4 2 601 8
4 3 609 8
alter system dump datafile 4 block min 1 block max 3;
RelFno: 4, BeginBlock: 9, Flag: 0, First: 76, Free: 63412
FFFFFFFFFFFFFFFF FF0F000000000000 0000000000000000 0000000000000000
上一次的:
RelFno: 4, BeginBlock: 9, Flag: 0, First: 72, Free: 63416
FFFFFFFFFFFFFFFF FF00000000000000 0000000000000000 0000000000000000
这次分配了4个区间,所以Free少了4个,First也增加了了4个,过去为什么First没有增加那么“正规”呢?因为这次是在EMP5后增加的EMP5,而以前的那个是在EMP4后加的EMP5.也就是说这个是连续的。EMP4占有一个区间。
三.释放空间,看位图变化
SQL> drop table scott.emp6;
表已删除。
SQL> alter system dump datafile 4 block min 1 block max 3;
系统已更改。
SQL> select file_id,extent_id,block_id,blocks from dba_extents
2 where segment_name='EMP6';
未选定行
alter system dump datafile 4 block min 1 block max 3;
RelFno: 4, BeginBlock: 9, Flag: 0, First: 76, Free: 63412
FFFFFFFFFFFFFFFF FF0F000000000000 0000000000000000 0000000000000000
上一次的:
RelFno: 4, BeginBlock: 9, Flag: 0, First: 76, Free: 63412
FFFFFFFFFFFFFFFF FF0F000000000000 0000000000000000 0000000000000000
没有改变
SQL> commit
提交完成。
alter system dump datafile 4 block min 1 block max 3;
RelFno: 4, BeginBlock: 9, Flag: 0, First: 76, Free: 63412
FFFFFFFFFFFFFFFF FF0F000000000000 0000000000000000 0000000000000000
Shutdown 后再 startup
RelFno: 4, BeginBlock: 9, Flag: 0, First: 76, Free: 63412
FFFFFFFFFFFFFFFF FF0F000000000000 0000000000000000 0000000000000000
为什么空间还是没有释放呢?可EMP6的区间已经不存在了。是不是有个UNDO时间在里面呢?
select segment_name,extent_id,block_id from dba_extents where file_id=4 order by block_id;
SEGMENT_NAME EXTENT_ID BLOCK_ID
EMP1 1 537
EMP4 0 545
EMP5 0 553
EMP5 1 561
EMP5 2 569
EMP5 3 577
看不出什么变化,那就再给emp5分配一个区间看看情况:
SQL> alter table scott.emp5 allocate extent;
表已更改。
SQL> commit;
提交完成。
SQL> alter system dump datafile 4 block min 1 block max 3;
RelFno: 4, BeginBlock: 9, Flag: 0, First: 77, Free: 63411
FFFFFFFFFFFFFFFF FF1F000000000000 0000000000000000 0000000000000000
以前的:
RelFno: 4, BeginBlock: 9, Flag: 0, First: 76, Free: 63412
FFFFFFFFFFFFFFFF FF0F000000000000 0000000000000000 0000000000000000
虽然删除了EM6,可占用的空间并没有真正释放。此处发现给EMP5新分配了一个区间仍在继续添加。有可能EMP6的占用空间还没有彻底释放才这样,请看:
可以查看回收站看看:
SQL> conn scott/m1234;
已连接。
SQL> show recyclebin;
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
EMP6 BIN$8gX3cLWCQcihPdfwS5foXg==$0 TABLE 2010-12-23:12:03:37
发现EMP6表仍在回收站中,那彻底删除看看情况:
SQL> purge table emp6;
表已清除。
SQL> show recyclebin;
SQL> conn system/m1234 as sysdba;
已连接。
SQL> alter system dump datafile 4 block min 1 block max 3;
系统已更改。
现在的:
RelFno: 4, BeginBlock: 9, Flag: 0, First: 72, Free: 63415
FFFFFFFFFFFFFFFF FF10000000000000 0000000000000000 0000000000000000
添加 emp5 一个区间后
RelFno: 4, BeginBlock: 9, Flag: 0, First: 77, Free: 63411
FFFFFFFFFFFFFFFF FF1F000000000000 0000000000000000 0000000000000000
以前的:
RelFno: 4, BeginBlock: 9, Flag: 0, First: 76, Free: 63412
FFFFFFFFFFFFFFFF FF0F000000000000 0000000000000000 0000000000000000
现在比以前少了4个区间的空间,证明是对的,需要清空回收站的表才能释放空间。以前的起始First: 76,添加一个区间First: 77,然后释放空间后First成了EMP6原来的区间位置(因为现在它不存在,而原来的它是存在的)。
SQL> select file_id,extent_id,block_id,blocks from dba_extents
2 where segment_name='EMP5';
FILE_ID EXTENT_ID BLOCK_ID BLOCKS
---------- ---------- ---------- ----------
4 0 553 8
4 1 561 8
4 2 569 8
4 3 577 8
4 4 617 8
总结:通过以上实验,可以发现区间的分配在位图上的显示很明显,Free和下面的位图显示都是很明显的,而First显示的并不明显,但会发现,First在这里不是顺序的,而是像个指针,它指向变化的地方,这个地方或者删除或者增加区间。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/22528444/viewspace-683083/ ,如需转载,请注明出处,否则将追究法律责任。