Oracle块中的行偏移量,Oracle DUL工做原理和技术实现

DUL工具是Oracle数据库挽救数据的最后手段,你用到DUL的时候,大部分状况下,数据库已经不能启动了,甚至有些数据文件已经损坏了。那么DUL又是怎样在这些极端的状况下把数据导出来的呢?下面咱们就来一步步的分析它的工做原理。若是你想本身开发一个相似的工具,这篇文章也会告诉你有那些工做要作,该怎样去作。数据库

Oracle数据库其实是一堆数据的集合,数据存储在表中,经过一些软件来管理这些数据,其中读取数据只是这些功能中的一小部分。在这些数据中最重要的就是用户数据,它们一般保存在数据文件中,按照必定的格式存储。这些数据怎样解释成咱们看到的样子,这就须要元数据的帮忙了,一般咱们把元数据叫作数据字典。下面咱们先来看看数据字典是什么样子。bootstrap

数据字典

Oracle的数据字典也是由一些表组成的。其中最主要的有obj$,tab$,col$这三张表,obj$表中指定了对象的名称,对象ID,对象的数据ID等,固然也指定了对象的属主ID。tab$表指定了表的一些属性,最主要的是它指定了表开始的位置,在哪一个数据文件中,从哪一个块开始。col$表指定了表的列属性,包括列的名称,列ID,列在段中的ID,列的类型,长度等等,有了col$中的信息,Oracle就能解释存储在数据块中的表的格式了。数据结构

表在数据文件中的位置

上面咱们说过,tab$表中有两个字段指定了表开始的位置,一个叫FILE#,指示表在哪一个数据文件中,另外一个叫BLOCK#,指示表从哪一个块开始。这个开始的块叫段头块,里面包含了一个个extent地址范围,叫作extent map,extent是由连续的数据块构成的。有了这个extent map,就能够从这些块中读取数据了,这些块就是表的数据块。若是一个表很是大,段头块并不能包含全部的extent,那怎么办呢?Oracle会在这个块中指定下一个extent map的块地址,直到全部的extent map都列举完毕。ide

有了上面的知识,咱们就能够从数据文件中读取表的数据了。在开始以前,好像还有一点问题,怎样从数据文件中读取数据字典表呢?数据字典也是表,表的段头位置又是从tab$中获得的,这时咱们尚未读到tab$的数据,好像陷入死循环了。别急,Oracle在启动的时候会遇到跟咱们同样的问题,它怎么来解决呢?原来Oracle启动时,先在内存中建立一个叫作bootstrap$的表,这个表中存储了一些建表语句,其中就包括了上面提到的obj$,tab$和col$,有趣的是,在每一个建表语句的后面,还指示了这个表的段头块位置,那么这下就方便了,直接到这个位置找到extent map,遍历全部的extent map找到属于这个表的数据块,解析数据块中的内容,就能够获得数据字典的信息了。

看到这里,你还有点困惑,那么说明你思考的深刻,是的,bootstrap$表的开始位置在哪里呢?它保存在1号数据文件的1号块中,这个块包含文件头信息,里面有个叫root dba的字段,包含的地址就是bootstrap$表的段头块地址。工具

数据块

数据块中包含了表中的数据,它也是有必定结构的,开始是块头信息,事务信息,下面是ITL,ITL大小是固定的,叫作事务槽,块中包含几个事务槽,在事务信息中指定。再后面就是数据头信息,紧接着是表目录(table directory)信息,后面是行目录(row directory),行目录指定了每行数据的位置。再后面就是行数据了,行数据是从块的底部往上来存储的,因此在行目录和真正的数据之间可能会有一部分空闲的空间。数据块的结构比较复杂,好在Oracle有一个工具叫作bbed,能够打开一个数据块,它详细定义了这些数据结构,包含数据结构的各个字段,能够方便的看到数据存储的细节。对象

long数据类型

LONG类型的数据通常比较长,很容易形成行链接,固然若是一个表建立时字段过多,也会形成行链接,就是说一行数据分布在了两个或多个数据块之间,这时怎么办呢?Oracle在每行数据开始都有一个叫作fb的字段,指示数据是否链接到了下一个块,若是到了下一个块,那么就会出现一个叫作nrid的字段,用来指示后面的数据链接到了哪里,这是一个地址,表明了在哪个块的哪一个偏移量。若是下一个块尚未彻底容纳这一行数据,那么会有下一个nrid,一直链接下去,直到数据行结束。索引

lob数据类型

LOB是大对象数据类型,是为了替代LONG类型引入的,当数据量比较小时,它存储在表的块内,若是数据比较大,就存储在表外的一个段中,这个段叫作LOB段。LOB数据在LOB段中的位置,由一个叫作定位器的字段来指定,英文名称叫作Lob Locator,这个定位器存储在表的数据块中,这样读到LOB字段时,就能够经过定位器找到LOB数据。事务

lob index

其实,LOB的存储是至关复杂的,默认的状况下,为了方便存储,LOB列在表的数据块中,不只存储了定位器,还存储了一些LOB数据块的地址,经过这些地址把LOB数据读出来。可是这些存储的地址个数是有限制的,这取决于表数据块中LOB信息的长度,默认状况下最可能是12个,若是超出了,就要用到定位器了,定位器不能直接找到LOB段的块位置,实际上他是LOB index的一个键值,经过这个键,在LOB索引中找到一系列的LOB块的地址,经过这些地址把LOB数据读出来。内存

SecureFile

上面谈到的LOB存储格式叫作BasicFile LOB,从11g开始,Oracle引入了一种新的LOB存储格式,叫作SecureFile LOB。它几乎把LOB index取消了,而是把LOB的块地址直接放在了LOB段的头块中,经过头块中的地址能够直接读取LOB数据。固然若是LOB数据量很大很大,头块也放不下这么多地址,那怎么办呢?Oracle在头块中设置了四个地址,分别叫作dba0,dba1,dba2,dba3。这是一个四级的内部树结构,dba0至关于一个叶子节点,管理了不少LOB数据块地址,当dba0满了,就会出现dba1,是dba0的上级节点,它又管理了不少相似dba0的叶子,每一个叶子节点块都包含了不少LOB数据块的地址,dba1满了,就会出现dba2节点,类推上去,到了dba3时,能管理的数据量已经远超过了LOB数据量的最大限制,这样全部的LOB数据都能经过这个结构遍历读取了。开发

recyclebin

若是你删除了表,从11g开始默认状况下并无真正删除,而是把表名改变了,原来的表名存储在了一个叫回收站的表中,若是你改变了主意,还能够经过命令恢复回来,对误删了表是一个好消息。因为它与普通表没有区别,因此经过上面的知识,咱们就能恢复回来。

truncate table

若是一个表被截断了,那可能你就真的访问不了原来的数据了,若是如今后悔了,也只能去撞墙了。用咱们前面介绍的方法能不能找回数据呢?找到表的段头块,dump出来看看,你会发现段头块中的extent map已经被清除了,这就无法经过extent map把数据遍历出来了。办法老是有的,数据不是都存储在数据文件中吗?那咱们把全部数据文件中的块都扫描一遍,把跟这个表的ID一致的那些块都找出来,而后从这些块中把数据都分析出来,不就能够了吗?只是花费的时间多一些,而且要保证不能遗漏了数据文件,实践证实仍是能够把数据读出来的。

drop table

有了上面截断表的经验,删除的表也就好处理了。段头块的改变几乎与截断表是同样的。与截断表不一样的是,你要先把数据字典中删除的记录恢复出来,obj$,tab$,col$表中关于这个表的记录都被删除了,那么怎样恢复呢?记得前面咱们提到过在每行数据前面都有一个叫作fb的字段,其实Oracle并无把这条数据清除掉,只是在fb字段上作了一个标记,去除这个标记,这些记录就都恢复了。下面再把数据文件扫描一遍,找到属于这个表的块,就能把数据恢复了。

数据字典损坏

最严重的状况就是数据文件中有部分已经损坏了,那么就不能保证彻底恢复数据了。那么首先仍是要尝试读取数据字典,Oracle对基础的数据字典表存储的段头块位置都是固定的,找一个相同版本的数据库,从bootstrap$表中查找到数据字典的段头位置,或者从tab$中找到段头位置,而后尝试从这些地方导出数据字典,若是能导出数据字典,剩下的工做就跟前面同样了。

最坏的状况就是系统表空间的数据文件丢失或者严重损坏,已经没法导出数据字典了,那么这时怎么办呢?那么只有经过数据来重建数据字典了,仍是把全部数据文件扫描一遍,记录段头块的位置,每一个段头块会对应一个表或一个分区,这样表的段头位置就找到了,接下来要作的就是重建col$中的字段,主要是数据类型,长度等。有些数据类型的长度是固定的,好比日期类型,时间戳类型,很好猜想。数字类型也有本身的特色比较好肯定,剩下的就是字符类型了,大部分猜想不到的均可以先当作字符类型处理。而后根据重建的数据字典导出一部分数据,这时就要经过人工比对,把字段类型肯定清楚,而后就能够导出数据了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值