Oracle DUL的工作原理和技术实现

想你就写信 2021-01-21 23:23:46
技术 工作 oracle 原理 dul


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$中的字段,主要是数据类型,长度等。有些数据类型的长度是固定的,比如日

期类型,时间戳类型,很好猜测。数字类型也有自己的特点比较好确定,剩下的就是字符类型了,大部分猜测不到的都可以先

当做字符类型处理。然后根据重建的数据字典导出一部分数据,这时就要通过人工比对,把字段类型确定清楚,然后就可以导

出数据了。

版权声明
本文为[想你就写信]所创,转载请带上原文链接,感谢
https://segmentfault.com/a/1190000039055097

  1. 【计算机网络 12(1),尚学堂马士兵Java视频教程
  2. 【程序猿历程,史上最全的Java面试题集锦在这里
  3. 【程序猿历程(1),Javaweb视频教程百度云
  4. Notes on MySQL 45 lectures (1-7)
  5. [computer network 12 (1), Shang Xuetang Ma soldier java video tutorial
  6. The most complete collection of Java interview questions in history is here
  7. [process of program ape (1), JavaWeb video tutorial, baidu cloud
  8. Notes on MySQL 45 lectures (1-7)
  9. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  10. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  11. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  12. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  13. 【递归,Java传智播客笔记
  14. [recursion, Java intelligence podcast notes
  15. [adhere to painting for 386 days] the beginning of spring of 24 solar terms
  16. K8S系列第八篇(Service、EndPoints以及高可用kubeadm部署)
  17. K8s Series Part 8 (service, endpoints and high availability kubeadm deployment)
  18. 【重识 HTML (3),350道Java面试真题分享
  19. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  20. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  21. [re recognize HTML (3) and share 350 real Java interview questions
  22. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  23. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  24. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  25. RPC 1: how to develop RPC framework from scratch
  26. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  27. RPC 1: how to develop RPC framework from scratch
  28. 一次性捋清楚吧,对乱糟糟的,Spring事务扩展机制
  29. 一文彻底弄懂如何选择抽象类还是接口,连续四年百度Java岗必问面试题
  30. Redis常用命令
  31. 一双拖鞋引发的血案,狂神说Java系列笔记
  32. 一、mysql基础安装
  33. 一位程序员的独白:尽管我一生坎坷,Java框架面试基础
  34. Clear it all at once. For the messy, spring transaction extension mechanism
  35. A thorough understanding of how to choose abstract classes or interfaces, baidu Java post must ask interview questions for four consecutive years
  36. Redis common commands
  37. A pair of slippers triggered the murder, crazy God said java series notes
  38. 1、 MySQL basic installation
  39. Monologue of a programmer: despite my ups and downs in my life, Java framework is the foundation of interview
  40. 【大厂面试】三面三问Spring循环依赖,请一定要把这篇看完(建议收藏)
  41. 一线互联网企业中,springboot入门项目
  42. 一篇文带你入门SSM框架Spring开发,帮你快速拿Offer
  43. 【面试资料】Java全集、微服务、大数据、数据结构与算法、机器学习知识最全总结,283页pdf
  44. 【leetcode刷题】24.数组中重复的数字——Java版
  45. 【leetcode刷题】23.对称二叉树——Java版
  46. 【leetcode刷题】22.二叉树的中序遍历——Java版
  47. 【leetcode刷题】21.三数之和——Java版
  48. 【leetcode刷题】20.最长回文子串——Java版
  49. 【leetcode刷题】19.回文链表——Java版
  50. 【leetcode刷题】18.反转链表——Java版
  51. 【leetcode刷题】17.相交链表——Java&python版
  52. 【leetcode刷题】16.环形链表——Java版
  53. 【leetcode刷题】15.汉明距离——Java版
  54. 【leetcode刷题】14.找到所有数组中消失的数字——Java版
  55. 【leetcode刷题】13.比特位计数——Java版
  56. oracle控制用户权限命令
  57. 三年Java开发,继阿里,鲁班二期Java架构师
  58. Oracle必须要启动的服务
  59. 万字长文!深入剖析HashMap,Java基础笔试题大全带答案
  60. 一问Kafka就心慌?我却凭着这份,图灵学院vip课程百度云