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

数据库版本如下:

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实现 蓝桥杯VIP 算法训练 装箱问题

    题目描述 有一个箱子容量为V(正整数0≤V≤20000),同时有n个物品(0<n≤30,每个物品有一个体积(正整数). 要求nn个物品中,任取若干个装入箱内,使箱子的剩余空间为最小. 输入输出格 ...

  2. Java实现 LeetCode 169 多数元素

    169. 多数元素 给定一个大小为 n 的数组,找到其中的多数元素.多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素. 你可以假设数组是非空的,并且给定的数组总是存在多数元素. 示例 1: 输 ...

  3. java代码(6) ---guava之multimap

    guava之multimap 上一篇说的是Multiset它可以对存入的相同元素做一个计数的功能,那multimap呢? 一.概述 1.基本介绍和案例说明 multimap和Multiset的继承结果 ...

  4. .NET Core Session源码探究

    前言     随着互联网的兴起,技术的整体架构设计思路有了质的提升,曾经Web开发必不可少的内置对象Session已经被慢慢的遗弃.主要原因有两点,一是Session依赖Cookie存放Session ...

  5. Java Review (一、Java开发环境)

    @ 目录 Java程序运行机制 高级语言运行机制 编译型语言 解释型语言 Java运行机制和JVM 编写 编译 运行 Java开发工具包 JDK JRE JDK.JRE与JVM HelloWord 编 ...

  6. System.PlatformNotSupportedException:“Operation is not supported on this platform.”

    vs2019创建.net core3.1 的控制台应用程序 执行以下代码: using System; using System.Diagnostics; using System.Threading ...

  7. OAuth + Security - 5 - Token存储升级(数据库、Redis)

    PS:此文章为系列文章,建议从第一篇开始阅读. 在我们之前的文章中,我们当时获取到Token令牌时,此时的令牌时存储在内存中的,这样显然不利于我们程序的扩展,所以为了解决这个问题,官方给我们还提供了其 ...

  8. 2.keras-构建基本网络实现非线性回归

    构建基本网络实现非线性回归 1.加载显示数据集 import tensorflow as tf import numpy as np import keras from keras.layers im ...

  9. 0.大话Spring Cloud

    天天说Spring cloud ,那到底它是什么? 定义 它不是云计算解决方案 它是一种微服务开发框架 它是(快速构建分布式系统的通用模式的)工具集 它基于Spring boot 构建开发 它是云原生 ...

  10. CentOS7.5搭建Hadoop2.7.6完全分布式集群

    一 完全分布式集群搭建 Hadoop官方地址:http://hadoop.apache.org/ 1  准备3台客户机 1.2 关闭防火墙,设置静态IP,主机名 关闭防火墙,设置静态IP,主机名此处略 ...