【Oracle】表碎片重用规则
看完该篇文章你可以了解如下问题:表碎片是如何产生的,这些碎片能否重用?
数据库版本如下:
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】表碎片重用规则的更多相关文章
- 08 Oracle表碎片查询以及整理(高水位线)
Oracle表碎片查询以及整理(高水位线) 1.表碎片的来源 当针对一个表的删除操作很多时,表会产生大量碎片.删除操作释放的空间不会被插入操作立即重用,甚至永远也不会被重用. 2.怎样确定是否有表碎片 ...
- Oracle 数据库整理表碎片
Oracle 数据库整理表碎片 转载:http://kyle.xlau.org/posts/table-fragmentation.html 表碎片的来源 当针对一个表的删除操作很多时,表会产生大量碎 ...
- Oracle表空间碎片整理SHRINK与MOVE
整理表碎片通常的方法是move表,当然move是不能在线进行的,而且move后相应的索引也会失效,oracle针对上述不足,在10g时加入了shrink,那这个方法能不能在生产中使用呢? ...
- 【转】Oracle 表空间与数据文件
--============================== --Oracle 表空间与数据文件 --============================== /* 一.概念 表空间:是一个或 ...
- Oracle 表空间与数据文件
-============================== --Oracle 表空间与数据文件 --============================== /* 一.概念 表空间:是一个或多 ...
- oracle表分区以及普表转分区表(转)
概述 Oracle的表分区功能通过改善可管理性.性能和可用性,从而为各式应用程序带来了极大的好处.通常,分区可以使某些查询以及维护操作的性能大大提高.此外,分区还可以极大简化常见的管理任务,分区是构建 ...
- oracle表分区详解
原文来自:http://www.cnblogs.com/leiOOlei/archive/2012/06/08/2541306.html oracle表分区详解 从以下几个方面来整理关于分区表的概念及 ...
- Oracle表空间知识
Oracle表空间知识 一,创建临时表空间 CREATE temporary TABLESPACE TEMP_PNLREPORT tempfile '/oradata2/ORCL/temp_pnlre ...
- 45.oracle表类型、数据拆分、表分区
不要做一些没有意义的事情,就比如说你要离职并不打算吃回头草,离职理由中完全没有必要说明“领导的水平太渣,人品太差”此类的原因,而是“个人原因”,当然实在不批准辞职另说. oracle表类型 表的类型分 ...
随机推荐
- 第四届蓝桥杯JavaB组国(决)赛真题
解题代码部分来自网友,如果有不对的地方,欢迎各位大佬评论 题目1.猜灯谜 题目描述 A 村的元宵节灯会上有一迷题: 请猜谜 * 请猜谜 = 请边赏灯边猜 小明想,一定是每个汉字代表一个数字,不同的汉字 ...
- java实现取球博弈
今盒子里有n个小球,A.B两人轮流从盒中取球,每个人都可以看到另一个人取了多少个,也可以看到盒中还剩下多少个,并且两人都很聪明,不会做出错误的判断. 我们约定: 每个人从盒子中取出的球的数目必须是:1 ...
- java实现第九届蓝桥杯三角形面积
三角形面积 小明最近在玩一款游戏.对游戏中的防御力很感兴趣. 我们认为直接影响防御的参数为"防御性能",记作d,而面板上有两个防御值A和B,与d成对数关系,A=2^d,B=3^d( ...
- ASP.NET Core Blazor Webassembly 之 路由
web最精妙的设计就是通过url把多个页面串联起来,并且可以互相跳转.我们开发系统的时候总是需要使用路由来实现页面间的跳转.传统的web开发主要是使用a标签或者是服务端redirect来跳转.那今天来 ...
- EasyARM-iMX257 linux两年前的笔记
我依然清晰的记得刚拿到Imx283 257的情景,兴奋中充满忧虑,对操作系统的概念只知一二,不知三四!!周立功出品的资料我一直觉得是比较精品的,同样这款iMX283配套的文档资料(v1.04)也是比较 ...
- Vue可响应式数组方法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 小师妹学JavaIO之:Buffer和Buff
目录 简介 Buffer是什么 Buffer进阶 创建Buffer Direct VS non-Direct Buffer的日常操作 向Buffer写数据 从Buffer读数据 rewind Buff ...
- centos7上安装memcached以及PHP安装memcached扩展(二)
开始在 PHP 中使用 Memcached 前, 我们需要确保已经安装了 Memcached 服务,接下来安装 php-memcached 扩展. PHP Memcached 扩展安装 第一步:如果 ...
- mysql内连接
inner join(等值连接) 只返回两个表中联结字段相等的行 select * from role_action ra INNER JOIN action a on ra.action_id = ...
- python基础整理(2)
布尔表达式与其余值的替换 值的测试 Python不仅仅可以使用布尔型变量作为条件,它可以直接在if中使用任何表达式作为条件: 大部分表达式的值都会被当作True,但以下表达式值会被当作False: F ...