关于数据库:Oracle-DUL的工作原理和技术实现

7次阅读

共计 3663 个字符,预计需要花费 10 分钟才能阅读完成。

DUL 工具是 Oracle 数据库解救数据的最初伎俩,你用到 DUL 的时候,大部分状况下,数据库曾经不能启动了,甚至有些

数据 文件曾经损坏了。那么 DUL 又是怎么在这些极其的状况下把数据导出来的呢?上面咱们就来一步步的剖析它的工作原理。

如 果你想本人开发一个相似的工具,这篇文章也会通知你有那些工作要做,该怎么去做。

Oracle 数据库实际上是一堆数据的汇合,数据存储在表中,通过一些软件来治理这些数据,其中读取数据只是这些性能

中的一小部分。在这些数据中最重要的就是用户数据,它们通常保留在数据文件中,依照肯定的格局存储。这些数据怎么解

释成咱们看到的样子,这就须要元数据的帮忙了,通常咱们把元数据叫做数据字典。上面咱们先来看看数据字典是什么样子。

数据字典

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 都列

举结束。

有了下面的常识,咱们就能够从数据文件中读取表的数据了。在开始之前,如同还有一点问题,怎么从数据文件中读取

数据字典表呢?数据字典也是表,表的段头地位又是从 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

下面谈到的 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