段中块的使用

Oracle内核技术揭密_吕海波  学习笔记

常说一个表就是一个段,但表和段是两个不同的概念,表是逻辑概念,比如表有几列,列的类型、长度,这些信息都属于表;段是物理概念,它只代表存储空间,区就属于段,一个段至少包含一个区。

oracle中每个对象都有一个ID,在DBA_OBJECTS视图中,object_id列是表ID,data_object_id列是段ID:

SQL> select object_id,data_object_id from dba_objects where owner='MA' and object_name='T62';

 OBJECT_ID DATA_OBJECT_ID
---------- --------------
     93456          93456

SQL> truncate table ma.t62;
SQL> insert into ma.t62 values(1,'a1');
SQL> commit;
SQL>  select object_id,data_object_id from dba_objects where owner='MA' and object_name='T62';

 OBJECT_ID DATA_OBJECT_ID
---------- --------------
     93456          93588

从上面的代码可知,刚开始表ma.t62的表ID和段ID都是93456,当truncate表后重新插入数据,表ID没变,段ID变为93588了。这是因为表ID创建后就不会再变,当truncate后,oracle会删除原来的段,再插入数据时会重新分配新的区,表就有了新的段,也就有了新的段ID。

块中空间的使用

常见的数据块大小为8K,它包含两部分信息:管理信息和用户数据。管理信息包括块头的SCN和ITL槽等。

当删除一行数据,再回滚,这行数据的物理位置是没有变的。当删除一行提交后,只是在这一行上做了一个删除标记,声明此行所占的空间可以被覆盖。当删除未提交时,事务加在行上的锁未释放,虽然做了删除标记,但仍不能被覆盖。删除行再回滚,由于原数据空间没有被其它数据覆盖,此时回滚段里的前镜像重新插入数据到原位置,不需要另外寻址。如果是删除提交后再插入,就需要重新寻址了,数据的物理位置就会发生变化。(PS:不明的为什么不是直接取消删除标记来达到回滚效果;难道与SCN号的变化有关?被删掉那笔数据的SCN号不可用?)

SQL> select dbms_rowid.rowid_relative_fno(rowid) fno,
       dbms_rowid.rowid_block_number(rowid) block_id,
       DBMS_ROWID.ROWID_ROW_NUMBER(rowid) row_id,
       id
from  ma.t62; 

       FNO   BLOCK_ID     ROW_ID         ID
---------- ---------- ---------- ----------
         8        133          0          1
         8        133          1          2
         8        133          2          3
         8        133          3          4

SQL> delete from ma.t62 where id=2;
SQL> select dbms_rowid.rowid_relative_fno(rowid) fno,
       dbms_rowid.rowid_block_number(rowid) block_id,
       DBMS_ROWID.ROWID_ROW_NUMBER(rowid) row_id,
       id
from  ma.t62;  2    3    4    5

       FNO   BLOCK_ID     ROW_ID         ID
---------- ---------- ---------- ----------
         8        133          0          1
         8        133          2          3
         8        133          3          4

SQL> rollback;
SQL> select dbms_rowid.rowid_relative_fno(rowid) fno,
       dbms_rowid.rowid_block_number(rowid) block_id,
       DBMS_ROWID.ROWID_ROW_NUMBER(rowid) row_id,
       id
from  ma.t62;  2    3    4    5

       FNO   BLOCK_ID     ROW_ID         ID
---------- ---------- ---------- ----------
         8        133          0          1
         8        133          1          2
         8        133          2          3
         8        133          3          4

oracle在插入行时,会在数据块中设一个标记位,记录空间使用到哪儿了。块中用户数据所占空间是从下往上分配的,假设往一个8192字节的块中插入5行,每行100字节,插入后标记位指到(8192-500)7692字节处。如果删除一行并提交,标记位的值不会变,当插入新行时,将会从7692处向上查找可用空间,删除行释放的空间不会被使用。当标记位值越来越小,向上达到管理信息的边界时,标记位会再变为8192。这也说明了删除提交后,再插入数据时位置发生变化的原因了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值