看完该篇文章你可以了解如下问题:表碎片是如何产生的,这些碎片能否重用?

数据库版本如下:

SYS@zkm> select banner from v$version where rownum=1;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

创建一张空表TT,由于是sys用户的表,不会延迟段创建。

因此可以看到区信息能够立刻查出来。

SYS@zkm> create table tt (id int,name varchar2(2000)) tablespace users;

Table created.

SYS@zkm> select extent_id,file_id,block_id,bytes,blocks from dba_extents where segment_name='TT' and owner='SYS';

 EXTENT_ID    FILE_ID   BLOCK_ID      BYTES     BLOCKS
---------- ---------- ---------- ---------- ----------
0 4 1960 65536 8

查看段头块,一般段头块是第一个L3块。

SYS@zkm> select HEADER_FILE,HEADER_BLOCK from dba_segments where OWNER='SYS' and SEGMENT_NAME='TT';

HEADER_FILE HEADER_BLOCK
----------- ------------
4 1962

查找L3块的目的是找出0号区能够存放数据的块。

dump出L3块截取部分数据如下。

SYS@zkm> select value from v$diag_info where name like '%De%';

VALUE
--------------------------------------------------------------------------------
/u01/app/oracle/diag/rdbms/zkm/zkm/trace/zkm_ora_2568.trc SYS@zkm> alter system dump datafile 4 block 1962; System altered. Extent Control Header
-----------------------------------------------------------------
Extent Header:: spare1: 0 spare2: 0 #extents: 1 #blocks: 8
last map 0x00000000 #maps: 0 offset: 2716
Highwater:: 0x010007ab ext#: 0 blk#: 3 ext size: 8
#blocks in seg. hdr's freelists: 0
#blocks below: 0
mapblk 0x00000000 offset: 0
Unlocked
--------------------------------------------------------
Low HighWater Mark :
Highwater:: 0x010007ab ext#: 0 blk#: 3 ext size: 8
#blocks in seg. hdr's freelists: 0
#blocks below: 0
mapblk 0x00000000 offset: 0
Level 1 BMB for High HWM block: 0x010007a8
Level 1 BMB for Low HWM block: 0x010007a8
--------------------------------------------------------
Segment Type: 1 nl2: 1 blksz: 8192 fbsz: 0
L2 Array start offset: 0x00001434
First Level 3 BMB: 0x00000000
L2 Hint for inserts: 0x010007a9
Last Level 1 BMB: 0x010007a8
Last Level II BMB: 0x010007a9
Last Level III BMB: 0x00000000
Map Header:: next 0x00000000 #extents: 1 obj#: 89302 flag: 0x10000000
Inc # 0
Extent Map
-----------------------------------------------------------------
0x010007a8 length: 8 Auxillary Map
--------------------------------------------------------
Extent 0 : L1 dba: 0x010007a8 Data dba: 0x010007ab
-------------------------------------------------------- Second Level Bitmap block DBAs
--------------------------------------------------------
DBA 1: 0x010007a9

综合以上信息可以得到:

   区0的范围是:
1960 L1块
1961 L2块
1962 L3块
1963 第一个存放数据的数据块
1964 第二个存放数据的数据块
1965 第三个存放数据的数据块
1966 第四个存放数据的数据块
1967 第五个存放数据的数据块 高水位线标志块:1963

插入一行会话并回滚。

SYS@zkm> insert into tt values(1,rpad('a',1800,'+'));

1 row created.

SYS@zkm> alter system flush buffer_cache;  --清空buffer cache,不然L3块中的高水位线标志点不会立刻刷新。

System altered.

SYS@zkm> rollback;

Rollback complete.

此时dump L3块可以看到高水位点变为1968号块,过程省略。

以下每四条记录放在一个块中。

SYS@zkm> insert into tt values(5,rpad('e',1804,'+'));

1 row created.

SYS@zkm> insert into tt values(5,rpad('e',1805,'+'));

1 row created.

SYS@zkm> insert into tt values(5,rpad('e',1805,'+'));

1 row created.

SYS@zkm> insert into tt values(5,rpad('e',1805,'+'));

1 row created.

SYS@zkm> commit;

Commit complete.

SYS@zkm> insert into tt values(5,rpad('e',1804,'+'));

1 row created.

SYS@zkm> insert into tt values(5,rpad('e',1805,'+'));

1 row created.

SYS@zkm> insert into tt values(5,rpad('e',1805,'+'));

1 row created.

SYS@zkm> insert into tt values(5,rpad('e',1805,'+'));

1 row created.

SYS@zkm> commit;

Commit complete.

SYS@zkm> insert into tt values(5,rpad('e',1804,'+'));

1 row created.

SYS@zkm> insert into tt values(5,rpad('e',1805,'+'));

1 row created.

SYS@zkm> insert into tt values(5,rpad('e',1805,'+'));

1 row created.

SYS@zkm> insert into tt values(5,rpad('e',1805,'+'));

1 row created.

SYS@zkm> commit;

Commit complete.

SYS@zkm> insert into tt values(5,rpad('e',1804,'+'));

1 row created.

SYS@zkm> insert into tt values(5,rpad('e',1805,'+'));

1 row created.

SYS@zkm> insert into tt values(5,rpad('e',1805,'+'));

1 row created.

SYS@zkm> insert into tt values(5,rpad('e',1805,'+'));

1 row created.

SYS@zkm> commit;

Commit complete.

SYS@zkm> insert into tt values(5,rpad('e',1804,'+'));

1 row created.

SYS@zkm> insert into tt values(5,rpad('e',1805,'+'));

1 row created.

SYS@zkm> insert into tt values(5,rpad('e',1805,'+'));

1 row created.

SYS@zkm> insert into tt values(5,rpad('e',1805,'+'));

1 row created.

SYS@zkm> commit;

Commit complete.

SYS@zkm> select id,substr(name,1,1),rowid,dbms_rowid.rowid_relative_fno(rowid) file#,dbms_rowid.rowid_block_number(rowid) block#,dbms_rowid.rowid_row_number(rowid) row# from tt;

        ID SUBS ROWID                   FILE#     BLOCK#       ROW#
---------- ---- ------------------ ---------- ---------- ----------
5 e AAAVzuAAEAAAAerAAA 4 1963 0
5 e AAAVzuAAEAAAAerAAB 4 1963 1
5 e AAAVzuAAEAAAAerAAC 4 1963 2
5 e AAAVzuAAEAAAAerAAD 4 1963 3
5 e AAAVzuAAEAAAAesAAA 4 1964 0
5 e AAAVzuAAEAAAAesAAB 4 1964 1
5 e AAAVzuAAEAAAAesAAC 4 1964 2
5 e AAAVzuAAEAAAAesAAD 4 1964 3
5 e AAAVzuAAEAAAAetAAA 4 1965 0
5 e AAAVzuAAEAAAAetAAB 4 1965 1
5 e AAAVzuAAEAAAAetAAC 4 1965 2 ID SUBS ROWID FILE# BLOCK# ROW#
---------- ---- ------------------ ---------- ---------- ----------
5 e AAAVzuAAEAAAAetAAD 4 1965 3
5 e AAAVzuAAEAAAAeuAAA 4 1966 0
5 e AAAVzuAAEAAAAeuAAB 4 1966 1
5 e AAAVzuAAEAAAAeuAAC 4 1966 2
5 e AAAVzuAAEAAAAeuAAD 4 1966 3
5 e AAAVzuAAEAAAAevAAA 4 1967 0
5 e AAAVzuAAEAAAAevAAB 4 1967 1
5 e AAAVzuAAEAAAAevAAC 4 1967 2
5 e AAAVzuAAEAAAAevAAD 4 1967 3 20 rows selected.

可以看到高水位线1968以下的块(1963-1967)都被用完。测试下删除某一行,提交后在新建会话插入新的一行,看是否会填补到被删除行的位置。

比如删除1966号块rowid为AAAVzuAAEAAAAeuAAB的块。

会话1:
SYS@zkm> delete from tt where rowid='AAAVzuAAEAAAAeuAAB'; 1 row deleted. SYS@zkm> commit; Commit complete. 会话2:
SYS@zkm> insert into tt values(5,rpad('e',1805,'+')); 1 row created. SYS@zkm> commit; Commit complete. SYS@zkm> select id,substr(name,1,1),rowid,dbms_rowid.rowid_relative_fno(rowid) file#,dbms_rowid.rowid_block_number(rowid) block#,dbms_rowid.rowid_row_number(rowid) row# from tt; ID SUBS ROWID FILE# BLOCK# ROW#
---------- ---- ------------------ ---------- ---------- ----------
5 e AAAVzuAAEAAAAerAAA 4 1963 0
5 e AAAVzuAAEAAAAerAAB 4 1963 1
5 e AAAVzuAAEAAAAerAAC 4 1963 2
5 e AAAVzuAAEAAAAerAAD 4 1963 3
5 e AAAVzuAAEAAAAesAAA 4 1964 0
5 e AAAVzuAAEAAAAesAAB 4 1964 1
5 e AAAVzuAAEAAAAesAAC 4 1964 2
5 e AAAVzuAAEAAAAesAAD 4 1964 3
5 e AAAVzuAAEAAAAetAAA 4 1965 0
5 e AAAVzuAAEAAAAetAAB 4 1965 1
5 e AAAVzuAAEAAAAetAAC 4 1965 2 ID SUBS ROWID FILE# BLOCK# ROW#
---------- ---- ------------------ ---------- ---------- ----------
5 e AAAVzuAAEAAAAetAAD 4 1965 3
5 e AAAVzuAAEAAAAeuAAA 4 1966 0
5 e AAAVzuAAEAAAAeuAAB 4 1966 1
5 e AAAVzuAAEAAAAeuAAC 4 1966 2
5 e AAAVzuAAEAAAAeuAAD 4 1966 3
5 e AAAVzuAAEAAAAevAAA 4 1967 0
5 e AAAVzuAAEAAAAevAAB 4 1967 1
5 e AAAVzuAAEAAAAevAAC 4 1967 2
5 e AAAVzuAAEAAAAevAAD 4 1967 3 20 rows selected.

可以看到高水位线以下有块能够容纳新行的话,会按照assm规则去选择这些块并插入数据(排除append)。在L1块中记录了所属数据块的存储状态,比如"0-25% free"或者full等。当然有不是full的情况下不代表可以insert进数据。比如0-25% free的时候,一行数据还是放不下的话会更新为full并且另找新的可以容纳下这一行数据的数据块。

那么如果高水位线以下存在块可以容纳插入的行,碎片又是如何产生的呢?

我们说频繁的dml会让表产生碎片,比如频繁insert会导致申请新区,提高高水位线,而后有频繁的delete使得空间空闲空间变得零碎,从而产生碎片。在insert是用append形式的时候,碎片问题会变得更严重。旧空间还未满,又申请新的空间。

【Oracle】表碎片重用规则的更多相关文章

  1. 08 Oracle表碎片查询以及整理(高水位线)

    Oracle表碎片查询以及整理(高水位线) 1.表碎片的来源 当针对一个表的删除操作很多时,表会产生大量碎片.删除操作释放的空间不会被插入操作立即重用,甚至永远也不会被重用. 2.怎样确定是否有表碎片 ...

  2. Oracle 数据库整理表碎片

    Oracle 数据库整理表碎片 转载:http://kyle.xlau.org/posts/table-fragmentation.html 表碎片的来源 当针对一个表的删除操作很多时,表会产生大量碎 ...

  3. Oracle表空间碎片整理SHRINK与MOVE

    整理表碎片通常的方法是move表,当然move是不能在线进行的,而且move后相应的索引也会失效,oracle针对上述不足,在10g时加入了shrink,那这个方法能不能在生产中使用呢?        ...

  4. 【转】Oracle 表空间与数据文件

    --============================== --Oracle 表空间与数据文件 --============================== /* 一.概念 表空间:是一个或 ...

  5. Oracle 表空间与数据文件

    -============================== --Oracle 表空间与数据文件 --============================== /* 一.概念 表空间:是一个或多 ...

  6. oracle表分区以及普表转分区表(转)

    概述 Oracle的表分区功能通过改善可管理性.性能和可用性,从而为各式应用程序带来了极大的好处.通常,分区可以使某些查询以及维护操作的性能大大提高.此外,分区还可以极大简化常见的管理任务,分区是构建 ...

  7. oracle表分区详解

    原文来自:http://www.cnblogs.com/leiOOlei/archive/2012/06/08/2541306.html oracle表分区详解 从以下几个方面来整理关于分区表的概念及 ...

  8. Oracle表空间知识

    Oracle表空间知识 一,创建临时表空间 CREATE temporary TABLESPACE TEMP_PNLREPORT tempfile '/oradata2/ORCL/temp_pnlre ...

  9. 45.oracle表类型、数据拆分、表分区

    不要做一些没有意义的事情,就比如说你要离职并不打算吃回头草,离职理由中完全没有必要说明“领导的水平太渣,人品太差”此类的原因,而是“个人原因”,当然实在不批准辞职另说. oracle表类型 表的类型分 ...

随机推荐

  1. Java实现约瑟夫斯问题

    1 问题描述 引用自<算法设计与分析基础>第三版: 约瑟夫斯问题,是以弗拉瓦斯.约瑟夫斯(Flavius Josephus)的名字命名的.约瑟夫斯是一个著名的犹太历史学家,参加并记录了公元 ...

  2. Java实现数字密码发生器

    在对银行账户等重要权限设置密码的时候,我们常常遇到这样的烦恼:如果为了好记用生日吧,容易被破解,不安全:如果设置不好记的密码,又担心自己也会忘记:如果写在纸上,担心纸张被别人发现或弄丢了- 这个程序的 ...

  3. opencl(3)程序、内核

    1:程序 1)从上下文中创建程序 cl_program clCreateProgramWithSource( cl_context context, //上下文 cl_uint count, //文本 ...

  4. 卷积生成对抗网络(DCGAN)---生成手写数字

    深度卷积生成对抗网络(DCGAN) ---- 生成 MNIST 手写图片 1.基本原理 生成对抗网络(GAN)由2个重要的部分构成: 生成器(Generator):通过机器生成数据(大部分情况下是图像 ...

  5. 2.3 sqlmap目录及结构

    2.3 sqlmap目录及结构Tips:此篇文章主要参考了<sqlmap从入门到精通>这本书中的相关具体细节,由于这本书作者完成的时间大概在2017年作用,所以我根据书中提到的信息再根据目 ...

  6. java 中有几种类型的流?

    字节流,字符流. 字节流继承于 InputStream \ OutputStream, 字符流继承于 InputStreamReader \ OutputStreamWriter. 在 java.io ...

  7. NativeXml实例训练时注意事项_1

    NativeXml实例训练: 1)使用NativeXml操作xml文件时,需要将几个单元文件在Library中引用,配置好这个后面的就可自由训练.或按照自己想要的组合折腾.       2)运行程序调 ...

  8. Spark GraphX企业运用

    ========== Spark GraphX 概述 ==========1.Spark GraphX是什么?  (1)Spark GraphX 是 Spark 的一个模块,主要用于进行以图为核心的计 ...

  9. MySQL数据表中有自增长主键时如何插入数据

    原文链接:https://blog.csdn.net/RuobaiMEN/article/details/79794199 MySQL数据库表中有自增主键ID,当用SQL插入语句中插入语句带有ID列值 ...

  10. css 那些使用小技巧(兼容性)

    1. inline-block 的兼容性问题 display:inline-block; *display:inline; *zoom:1; 2. Microsoft Edge 自动给数字加下划线 在 ...