[20190101]块内重整.txt
[20190101]块内重整.txt
--//我不知道用什么术语表达这样的情况,我仅仅一次开会对方这么讲,我现在也照用这个术语.
--//当dml插入数据到数据块时,预留一定的空间(pctfree的百分比)不再插入.保留一些空间主要目的为了ITL的增加,以及update时空间增长.
--//避免大量的行迁移情况出现.
--//当到达顶部时,会出现一次块内重整(也有叫块内重组).通过演示了解这个过程.
1.环境:
SCOTT@test01p> @ ver1
PORT_STRING VERSION BANNER CON_ID
-------------------- ---------- ---------------------------------------------------------------------------- ------
IBMPC/WIN_NT64-9.1.0 12.2.0.1.0 Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production 0
SCOTT@test01p> create table t as select rownum id,to_char(rownum)||lpad('x',800,'x') name from dual connect by level<=8;
Table created.
SCOTT@test01p> @desc t
Name Null? Type
---- -------- -------------
ID NUMBER
NAME VARCHAR2(840)
--//name 定义VARCHAR2(840).
SCOTT@test01p> select rowid ,id from t;
ROWID ID
------------------ --
AAAF61AALAAAACrAAA 1
AAAF61AALAAAACrAAB 2
AAAF61AALAAAACrAAC 3
AAAF61AALAAAACrAAD 4
AAAF61AALAAAACrAAE 5
AAAF61AALAAAACrAAF 6
AAAF61AALAAAACrAAG 7
AAAF61AALAAAACrAAH 8
8 rows selected.
--//有8条记录在一个块中.
SCOTT@test01p> @rowid AAAF61AALAAAACrAAA
OBJECT FILE BLOCK ROW ROWID_DBA DBA TEXT
---------- ---------- ---------- ---------- -------------------- -------------------- ----------------------------------------
24245 11 171 0 0x2C000AB 11,171 alter system dump datafile 11 block 171
SCOTT@test01p> alter system checkpoint ;
System altered.
2.通过bbed观察:
BBED> set dba 11,172
DBA 0x02c000ac (46137516 11,172)
--//windows版本block+1.
BBED> map
File: D:\APP\ORACLE\ORADATA\TEST\TEST01P\USERS01.DBF (11)
Block: 172 Dba:0x02c000ac
------------------------------------------------------------
KTB Data Block (Table/Cluster)
struct kcbh, 20 bytes @0
struct ktbbh, 96 bytes @20
struct kdbh, 14 bytes @124
struct kdbt[1], 4 bytes @138
sb2 kdbr[8] @142
ub1 freespace[1550] @158
ub1 rowdata[6480] @1708
ub4 tailchk @8188
BBED> p kdbr
sb2 kdbr[0] @142 7254
sb2 kdbr[1] @144 6444
sb2 kdbr[2] @146 5634
sb2 kdbr[3] @148 4824
sb2 kdbr[4] @150 4014
sb2 kdbr[5] @152 3204
sb2 kdbr[6] @154 2394
sb2 kdbr[7] @156 1584
BBED> x /rnc *kdbr[0]
rowdata[5670] @7378
-------------
flag@7378: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@7379: 0x00
cols@7380: 2
col 0[2] @7381: 1
col 1[801] @7384: 1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ..trunc.
--//注这里的偏移是相对偏移 7254+124(kdbh地址) = 7378.
--//共占用3+1+2+3+801 = 810,注前面有1个字节保持长度指示器.另外注意字符串长度大于250,需要使用3个字节保存长度指示器.
--//可以从数据的偏移量可以看出数据是从块底开始插入的.当前空余空间是1550.
3.继续测试,删除部分数据:
--//先删除一部分数据,仅仅打上标识标识删除.
SCOTT@test01p> delete from t where id in (1,3,6,7);
4 rows deleted.
SCOTT@test01p> commit ;
Commit complete.
SCOTT@test01p> alter system checkpoint ;
System altered.
--//通过bbed观察:
BBED> map
File: D:\APP\ORACLE\ORADATA\TEST\TEST01P\USERS01.DBF (11)
Block: 172 Dba:0x02c000ac
------------------------------------------------------------
KTB Data Block (Table/Cluster)
struct kcbh, 20 bytes @0
struct ktbbh, 96 bytes @20
struct kdbh, 14 bytes @124
struct kdbt[1], 4 bytes @138
sb2 kdbr[8] @142
ub1 freespace[1550] @158
ub1 rowdata[6480] @1708
ub4 tailchk @8188
--//删除部分记录,freespace空间保持不变.
BBED> p kdbr
sb2 kdbr[0] @142 7254
sb2 kdbr[1] @144 6444
sb2 kdbr[2] @146 5634
sb2 kdbr[3] @148 4824
sb2 kdbr[4] @150 4014
sb2 kdbr[5] @152 3204
sb2 kdbr[6] @154 2394
sb2 kdbr[7] @156 1584
BBED> x /rnc *kdbr[0]
rowdata[5670] @7378
-------------
flag@7378: 0x3c (KDRHFL, KDRHFF, KDRHFD, KDRHFH)
lock@7379: 0x02
cols@7380: 0
--//仅仅flag从2c变成3c,加入了KDRHFD标识.
4.然后修改一部分数据看看:
SCOTT@test01p> update t set name=lpad('a',811,'a') where id=2;
1 row updated.
SCOTT@test01p> commit ;
Commit complete.
SCOTT@test01p> alter system checkpoint ;
System altered.
--//我修改的长度与原来不等,这样增加长度增加10个字节.这样还剩下1550-820 = 730字节.
--//验证看看:
BBED> map
File: D:\APP\ORACLE\ORADATA\TEST\TEST01P\USERS01.DBF (11)
Block: 172 Dba:0x02c000ac
------------------------------------------------------------
KTB Data Block (Table/Cluster)
struct kcbh, 20 bytes @0
struct ktbbh, 96 bytes @20
struct kdbh, 14 bytes @124
struct kdbt[1], 4 bytes @138
sb2 kdbr[8] @142
ub1 freespace[730] @158
ub1 rowdata[7300] @888
ub4 tailchk @8188
--//ok正确!!
BBED> p kdbr
sb2 kdbr[0] @142 7254
sb2 kdbr[1] @144 764
sb2 kdbr[2] @146 5634
sb2 kdbr[3] @148 4824
sb2 kdbr[4] @150 4014
sb2 kdbr[5] @152 3204
sb2 kdbr[6] @154 2394
sb2 kdbr[7] @156 1584
--//kdbr[1] 指向新的位置.对应id=2的记录.其它不动.
BBED> x /rnc *kdbr[1]
rowdata[0] @888
----------
flag@888: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@889: 0x03
cols@890: 2
col 0[2] @891: 2
col 1[811] @894: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa... trunc..
--//如果继续修改记录,长度消耗大于730并且长度与原来不一样,这样就会出现块内重整的情况:
SCOTT@test01p> update t set name=lpad('b',811,'b') where id=4;
1 row updated.
SCOTT@test01p> commit ;
Commit complete.
SCOTT@test01p> alter system checkpoint ;
System altered.
BBED> map
File: D:\APP\ORACLE\ORADATA\TEST\TEST01P\USERS01.DBF (11)
Block: 172 Dba:0x02c000ac
------------------------------------------------------------
KTB Data Block (Table/Cluster)
struct kcbh, 20 bytes @0
struct ktbbh, 96 bytes @20
struct kdbh, 14 bytes @124
struct kdbt[1], 4 bytes @138
sb2 kdbr[8] @142
ub1 freespace[4762] @158
ub1 rowdata[3268] @4920
ub4 tailchk @8188
--//freespace变成了4762,出现一次块内重整,而且收回删除记录的空间.
BBED> p kdbr
sb2 kdbr[0] @142 8062
sb2 kdbr[1] @144 7242
sb2 kdbr[2] @146 7240
sb2 kdbr[3] @148 4796
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~当前偏移最小.
sb2 kdbr[4] @150 6430
sb2 kdbr[5] @152 6428
sb2 kdbr[6] @154 6426
sb2 kdbr[7] @156 5616
--//可以发现行目录发生变化对比前面的情况,做了整理,整体下移.我前面删除的记录是id in (1,3,6,7);
--//id=6,7的记录应该对应kdbr[5],kdbr[6],可以发现记录的偏移地址6428,6426,挨的很近.
--//可以大致猜测它的算法,移动除kdbr[3](对应id=4)的记录下移腾出空间,你可以发现kdbr[3]指向的偏移是当前最小的.
BBED> x /rnc *kdbr[5]
rowdata[1632] @6552
-------------
flag@6552: 0x3c (KDRHFL, KDRHFF, KDRHFD, KDRHFH)
lock@6553: 0x02
cols@6554: 0
BBED> x /rnc *kdbr[6]
rowdata[1630] @6550
-------------
flag@6550: 0x3c (KDRHFL, KDRHFF, KDRHFD, KDRHFH)
lock@6551: 0x02
cols@6552: 0
BBED> dump /v offset 6550 count 20
File: D:\APP\ORACLE\ORADATA\TEST\TEST01P\USERS01.DBF (11)
Block: 172 Offsets: 6550 to 6569 Dba:0x02c000ac
-----------------------------------------------------------------------------------------------------------
3c023c02 2c000202 c106fe21 03357878 78787878 l <.<.,...??.5xxxxxx
<32 bytes per line>
--//仅仅保留2个字节.
BBED> x /rnc *kdbr[0]
rowdata[3266] @8186
-------------
flag@8186: 0x3c (KDRHFL, KDRHFF, KDRHFD, KDRHFH)
lock@8187: 0x02
cols@8188: 0
BBED> dump /v count 20
File: D:\APP\ORACLE\ORADATA\TEST\TEST01P\USERS01.DBF (11)
Block: 172 Offsets: 8186 to 8191 Dba:0x02c000ac
-----------------------------------------------------------------------------------------------------------
3c020106 ff18 l <.....
<32 bytes per line>
--//这个时候按照以前使用bbed修复删除记录的方法是无用的.因为对应的记录信息已经被覆盖了.
5.继续插入记录看看.
SCOTT@test01p> insert into t values(9,to_char(9)||lpad('y',800,'y'));
1 row created.
SCOTT@test01p> commit ;
Commit complete.
SCOTT@test01p> alter system checkpoint ;
System altered.
--//当前块已经空出许多空间,可以继续插入数据,看看这时的情况:
BBED> map
File: D:\APP\ORACLE\ORADATA\TEST\TEST01P\USERS01.DBF (11)
Block: 172 Dba:0x02c000ac
------------------------------------------------------------
KTB Data Block (Table/Cluster)
struct kcbh, 20 bytes @0
struct ktbbh, 96 bytes @20
struct kdbh, 14 bytes @124
struct kdbt[1], 4 bytes @138
sb2 kdbr[9] @142
ub1 freespace[3950] @160
ub1 rowdata[4078] @4110
ub4 tailchk @8188
--//还有freespace=3950.
BBED> p kdbr
sb2 kdbr[0] @142 2
sb2 kdbr[1] @144 7242
sb2 kdbr[2] @146 5
sb2 kdbr[3] @148 4796
sb2 kdbr[4] @150 6430
sb2 kdbr[5] @152 6
sb2 kdbr[6] @154 -1
sb2 kdbr[7] @156 5616
sb2 kdbr[8] @158 3986
--//可以发现当前块又插入1条.
BBED> x /rnc *kdbr[8]
rowdata[0] @4110
----------
flag@4110: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@4111: 0x02
cols@4112: 2
col 0[2] @4113: 9
col 1[801] @4116: 9yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy..trunc..
--//注意看前面的kdbr[0],kdbr[2],kdbr[5],kdbr[6]对应的偏移量(2,5,6,-1),通过偏移量链接起来.
--//也就是这个这时的偏移量指向的地址根本不是rowdate区域.
--//我不知道是否可以得出这样结论:如果kdbr指向的值如果小于当前的行目录数量(9),这些行对应的记录应该是删除的.
--//理论讲这时对应记录很难恢复,已经覆盖了.
6.测试重用的情况:
--//是否会重用呢?理论讲应该会重用.打开新的会话看看:
SCOTT@test01p> insert into t values(10,to_char(10)||lpad('x',800,'x'));
1 row created.
SCOTT@test01p> commit ;
Commit complete.
SCOTT@test01p> alter system checkpoint;
System altered.
BBED> map
File: D:\APP\ORACLE\ORADATA\TEST\TEST01P\USERS01.DBF (11)
Block: 172 Dba:0x02c000ac
------------------------------------------------------------
KTB Data Block (Table/Cluster)
struct kcbh, 20 bytes @0
struct ktbbh, 96 bytes @20
struct kdbh, 14 bytes @124
struct kdbt[1], 4 bytes @138
sb2 kdbr[9] @142
ub1 freespace[3139] @160
ub1 rowdata[4889] @3299
ub4 tailchk @8188
--//freespace=3139.
BBED> p kdbr
sb2 kdbr[0] @142 3175
sb2 kdbr[1] @144 7242
sb2 kdbr[2] @146 5
sb2 kdbr[3] @148 4796
sb2 kdbr[4] @150 6430
sb2 kdbr[5] @152 6
sb2 kdbr[6] @154 -1
sb2 kdbr[7] @156 5616
sb2 kdbr[8] @158 3986
--//理论讲不同的会话不会插入相同的块,因为我建表比较特殊,使用ctas建立的.
--//可以发现插入占用了kdbr[0].
BBED> x /rnc *kdbr[0]
rowdata[0] @3299
----------
flag@3299: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@3300: 0x03
cols@3301: 2
col 0[2] @3302: 10
col 1[802] @3305: 10xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...trunc..
SCOTT@test01p> select rowid,id from t;
ROWID ID
------------------ ----------
AAAF61AALAAAACrAAA 10
AAAF61AALAAAACrAAB 2
AAAF61AALAAAACrAAD 4
AAAF61AALAAAACrAAE 5
AAAF61AALAAAACrAAH 8
AAAF61AALAAAACrAAI 9
6 rows selected.
--//oracle在插入时能快速定位到kdbr[0],估计在块内有相关记录.
BBED> p kdbh
struct kdbh, 14 bytes @124
ub1 kdbhflag @124 0x00 (NONE)
b1 kdbhntab @125 1
b2 kdbhnrow @126 9
sb2 kdbhfrre @128 2
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sb2 kdbhfsbo @130 36
sb2 kdbhfseo @132 3175
b2 kdbhavsp @134 3147
b2 kdbhtosp @136 3147
--//猜测记录在kdbh.kdbhfrre中,当前是2.如果继续插入,变成5就可以验证我的判断。
--//注意在新的会话插入(session 2):
SCOTT@test01p> insert into t values(11,to_char(11)||lpad('w',800,'w'));
1 row created.
SCOTT@test01p> commit ;
Commit complete.
SCOTT@test01p> alter system checkpoint;
System altered.
BBED> map
File: D:\APP\ORACLE\ORADATA\TEST\TEST01P\USERS01.DBF (11)
Block: 172 Dba:0x02c000ac
------------------------------------------------------------
KTB Data Block (Table/Cluster)
struct kcbh, 20 bytes @0
struct ktbbh, 96 bytes @20
struct kdbh, 14 bytes @124
struct kdbt[1], 4 bytes @138
sb2 kdbr[9] @142
ub1 freespace[2328] @160
ub1 rowdata[5700] @2488
ub4 tailchk @8188
--//freespace继续减少。
BBED> p kdbr
sb2 kdbr[0] @142 3175
sb2 kdbr[1] @144 7242
sb2 kdbr[2] @146 2364
sb2 kdbr[3] @148 4796
sb2 kdbr[4] @150 6430
sb2 kdbr[5] @152 6
sb2 kdbr[6] @154 -1
sb2 kdbr[7] @156 5616
sb2 kdbr[8] @158 3986
--//插入记录占用了kdbr[2]。
BBED> p kdbh
struct kdbh, 14 bytes @124
ub1 kdbhflag @124 0x00 (NONE)
b1 kdbhntab @125 1
b2 kdbhnrow @126 9
sb2 kdbhfrre @128 5
--//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~变成5,验证的判断。
sb2 kdbhfsbo @130 36
sb2 kdbhfseo @132 2364
b2 kdbhavsp @134 2336
b2 kdbhtosp @136 2336
--//这样通过kdbr[5],里面记录的是6,继续插入可以很容易行目录,最后记录-1,表示已经没有了。
SCOTT@test01p> select rowid,id from t;
ROWID ID
------------------ ----------
AAAF61AALAAAACrAAA 10
AAAF61AALAAAACrAAB 2
AAAF61AALAAAACrAAC 11
AAAF61AALAAAACrAAD 4
AAAF61AALAAAACrAAE 5
AAAF61AALAAAACrAAH 8
AAAF61AALAAAACrAAI 9
7 rows selected.
总结:
--//仅仅通过一些简单的例子演示这个过程,也许许多情况下更加复杂.
[20190101]块内重整.txt的更多相关文章
- 【Python文件处理】递归批处理文件夹子目录内所有txt数据
因为有个需求,需要处理文件夹内所有txt文件,将txt里面的数据筛选,重新存储. 虽然手工可以做,但想到了python一直主张的是自动化测试,就想试着写一个自动化处理数据的程序. 一.分析数据格式 需 ...
- Firefox 对条件判断语句块内的函数声明的处理与其他浏览器有差异
标准参考 函数声明和函数表达式 定义一个函数有两种途径:函数声明和函数表达式. 函数声明: function Identifier ( FormalParameterList opt ) { Func ...
- C语言块内变量回收问题
之前有一个错误认识,错误的认为局部变量的回收是发生在函数返回时.其实在块结束时块内使用的内容就会被回收了. 以下的实例说明了问题 ]; ; i < ; ++i) { int item = i; ...
- HTML div块内剧中
在HTML中有一个块内元素剧中的方法 那就是margin:0 auto; 剧中前 剧中后
- 【css对齐】块内或者行内图片与文字居中对齐最靠谱的方式!
块内或者行内图片与文字居中对齐最靠谱的方式! 做图片与文字在一行的按钮时候最常用到,总结了一个靠谱的方法,终于可以完美的对齐下面给个代码 首先是html: <p class="btnU ...
- pins-模块内的代码及资源隔离方案
随着项目的不断迭代,复杂的业务模块及项目自身的基础技术组件迅速扩张,以往基于单个模块的项目往往显得过于臃肿.代码目录结构,包名混乱,代码模块职责不清晰,耦合度高,不便维护.基础公共组件没有抽取并剥离干 ...
- 将多个文件夹内的txt合并
import os import re def text_create(name): """ 创建txt文件夹 """ desktop_pa ...
- python实现将文件夹内所有txt文件合并成一个文件
新建一个文件夹命名为yuliao,把所有txt文件放进去就ok啦!注意路径中‘/’,windows下路径不是这样. #coding=utf-8 import os #获取目标文件夹的路径 filed ...
- 利用MFC在控件内将txt中的数据画图
1:采集txt文件中的数据测试程序如下: #include "stdafx.h" #include <fstream> #include "iostream& ...
随机推荐
- 代理模式(静态代理、JDK动态代理原理分析、CGLIB动态代理)
代理模式 代理模式是设计模式之一,为一个对象提供一个替身或者占位符以控制对这个对象的访问,它给目标对象提供一个代理对象,由代理对象控制对目标对象的访问. 那么为什么要使用代理模式呢? 1.隔离,客户端 ...
- Web Service 部分内容简述(2)
1. CORBA是什么?用途是什么? CORBA 标准是公共对象请求代理结构(Common Object Request Broker Architecture),由对象管理组织 (Object M ...
- (转)MySQL join语法解析与性能分析
文章转载的:http://www.cnblogs.com/BeginMan/p/3754322.html 一.join语法概述 join用于多表中字段之间的联系,语法如下: ... FROM tabl ...
- Spring Cloud Stream消费失败后的处理策略(四):重新入队(RabbitMQ)
应用场景 之前我们已经通过<Spring Cloud Stream消费失败后的处理策略(一):自动重试>一文介绍了Spring Cloud Stream默认的消息重试功能.本文将介绍Rab ...
- 十大经典排序算法详细总结(含JAVA代码实现)
原文出处:http://www.cnblogs.com/guoyaohua/p/8600214.html 0.排序算法说明 0.1 排序的定义 对一序列对象根据某个关键字进行排序. 0.2 术语说明 ...
- zepto 事件分析3(add函数)
在上一篇的分析中,最后$.on方法返回了一个add方法函数的执行,在这里先看一下其代码: function add(element, events, fn, data, selector, deleg ...
- 一个小时学会Maven
一.为什么要Maven 在开发中经常需要依赖第三方的包,包与包之间存在依赖关系,版本间还有兼容性问题,有时还里要将旧的包升级或降级,当项目复杂到一定程度时包管理变得非常重要. Maven是当前最受欢迎 ...
- 32.QT-制作最强电压电阻表盘,可以自定义阴影效果,渐变颜色,图标,文字标签等-附带demo程序
由于上位机需要绘制电压电阻表盘,如下图所示: 后来,在网上找阿找,还是没找到满意的,索性自己来画控件算了,由于第一次画控件,所以花了我2天时间,才画好 效果图如下: 上图的所有颜色(包括滑动的渐变/单 ...
- 推荐 3 篇关于 java8 Lambda表达式的文章
State of the Lambda 这篇主要讲 Labmbda 的背景和用法 译文:深入理解Java 8 Lambda(语言篇--lambda,方法引用,目标类型和默认方法) State of t ...
- Java高并发 -- 线程池
Java高并发 -- 线程池 主要是学习慕课网实战视频<Java并发编程入门与高并发面试>的笔记 在使用线程池后,创建线程变成了从线程池里获得空闲线程,关闭线程变成了将线程归坏给线程池. ...