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

数据库版本如下:

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中lang包的常用方法介绍

    JAVA API(图片来源:实验楼) 包装类 Integer包装类 方法 返回值 功能描述 byteValue() byte 以 byte 类型返回该 Integer 的值 intValue() in ...

  2. java实现洛谷P1308统计单词数

    题目描述 一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数. 现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在给 ...

  3. 阿里巴巴 《Java 开发者手册》+ IDEA编码插件

    4月22日,阿里巴巴发布了泰山版<Java 开发手册>,以前以为终极版就真的是终极版了,没想到还是想的太简单了,继终极版之后又发布了详尽版.华山版,这不,泰山版又来了.想想也对,行业一直在 ...

  4. 大顶堆与小顶堆应用---寻找前k小数

    vector<int> getLeastNumber(vector<int>& arr,int k){ vector<int> vec(k,); if(== ...

  5. iOS -NSOperation——高级的并发处理方法

    NSOperation是Objective-C中一种高级的并发处理方法,现在对GCD的封装;功能比GCD更强大! 两个概念      操作:      操作队列:      NSOperation多线 ...

  6. ZooKeeper搭建集群

    ZooKeeper ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件.它是一个为分布式应用提供一致性 ...

  7. Kubernetes内部域名解析的那些事儿

    前言 在kubernets环境中,服务发现大都是基于内部域名的方式.那么就涉及到内部域名的解析.从1.11版本开始,kubeadm已经使用第三方的CoreDNS替换官方的kubedns作为集群内部域名 ...

  8. [Computer Vision]Harris角点检测的详细推导

    Harris角点检测 思想 为什么要检测角点呢?因为角点的特征比较明显.进行角点检测的朴素思想是利用图像梯度,也就是根据图像强度的变化来寻找角点.如图所示 这里举了个例子,给定一个小的区域(Patch ...

  9. Redis Desktop Manager无法连接虚拟机中启动的redis服务问题排查步骤

    Redis Desktop Manager下载地址 https://redisdesktop.com/download 安装好以后连接linux服务器上的Redis服务器错误: 问题排查: 1.检查R ...

  10. Windows10 下安装和配置Redis

    原文链接:https://blog.csdn.net/linghugoolge/article/details/86608897 一.下载地址https://github.com/MicrosoftA ...