derby数据库源码分析(一)--页面分析_起名字太难了的博客-程序员信息网

技术标签: apache  源代码  derby  数据库  源码  

一直以来都对数据库充满了好奇,想知道数据库底层的运作模式,为什么它可以做到高效存储,为什么可以做到ACID,锁机制如何实现。。。等等一系列的问题。

后来找到了Apache的顶级开源项目Derby数据库,该数据库可以支持目前主流的关系型数据库功能,并且代码量不大(20几M)。通过对数据库源代码的研究能够了解更多数据库底层的秘密。

首先先以Derby数据库的底层页面的格式说起。这个页面指的是存储数据库记录的一般页面。Derby数据库的页面默认大小为4096字节。

Format id(2)

页面头部(60)

数据库记录

Slot

校验和(8)

上述表格括号里面的数字表示其占页面的大小,单位是字节。

上述表格中的第一个部分是format id,在derby数据库中对每一个需要存储到磁盘的类分配了一个format id。比如页面对应的类为StoredPage,如果将StoredPage对应的对象写入磁盘时,首先需要将该类对应的format id写入磁盘。这样,当从磁盘读取数据时,可以通过format id找到对应的类,进而在内存中还原该对象。StorePage的format id是117。

每一个页面都有一个页面头部(header),页面头部大小固定,占60个字节。里面包括的内容有:

名字

长度(单位byte)

类型

描述

溢出标志

1

Boolean

表示该页面是否允许溢出

页面状态

1

Byte

 

页面版本

8

Long

页面每修改一次,该字段加一

Slot个数

2

Short

表示该页面中slot的个数

下一个记录id

4

Int

本页面中下一个可以使用的记录id,页面中记录id是唯一的,从6开始。

页面的generation number

4

Int

保留字段,默认值为0

页面前previous generation

4

Int

保留字段,默认值为0

Beforeimage页面的位置

8

 

保留字段,默认值为0

删除的记录数

2

Short

 

空闲百分比

2

Short

为页面更新预留的空间,目前有两个默认值0和20。用户自己创建表的页面是20。

保留空间

2

Short

 

保留空间

4

Int

 

保留空间

8

Long

 

保留空间

8

Long

 

头部信息长度为58个字节。一个页面共有两个状态:VALID_PAGE,INVALID_PAGE。如果页面空间被收回,那么页面状态为INVALID_PAGE,除此之外,页面状态为VALID_PAGE。页面在初始创建的时候,都是VALID_PAGE。

在页面中还有一部分区域叫做slot区域,slot区域中的每一个entry都对应了页面中的一条记录。如果页面大小为4096字节,那么一个entry占6个字节,如果为8192个字节,那么一个entry占12个字节。entry中包括三部分:对应记录在页面中的偏移位置,对应记录的总长度,为对应记录预留的空间长度。从entry中的内容可以看出,entry可以唯一确定一个记录,entry中三个部分的数据均分entry的空间。其中第三个数据为对应记录预留的空间长度的含义是:如果当前记录溢出,那么数据库会为该记录预留一部分空间;如果当前记录过小,以至于不足12个字节,那么数据库也会为当前记录预留一部分空间,以使该记录占的空间大小达到12个字节。页面中slot的空间是倒着增长的,如下图:


从上图就可以看出,页面中的entry是从大地址往小地址增长,而记录是从小地址往大地址增长。

每一个记录由两部分组成:记录头部,若干个列。其中每一个列又分为两部分:列头部,列值。列值存储的就是数据库数据。也就是说,如果对数据库中某一列赋值为字符串“1”,那么列值这一部分就是“1”。列头部和记录头部存储的是控制信息和状态信息。下面分别来说明。

对于记录头部:

名称

长度(单位字节)

说明

记录状态

1

 

记录id

压缩int,长度可以为1,2,4

从6开始

溢出页号

压缩long,长度可以为2,4,8

可以为空

溢出id

压缩int,长度可以为1,2,4

可以为空

第一列

压缩int,长度可以为1,2,4

用于表示第一列是哪一列,从0开始计数

列个数

压缩int,长度可以为1,2,4

当前行中共有多个域

为了节省空间,记录头部大量使用压缩格式存储。记录状态共有四个:

状态

说明

RECORD_DELETED

表示该记录是否已经被删除

RECORD_OVERFLOW

表示该记录是否溢出,如果溢出,那么列值部分填写的内容就是溢出页和溢出id

RECORD_HAS_FIRST_FIELD

表示该记录中含有第一列

RECORD_VALID_MASK

调试使用

列头部:

名称

长度(单位字节)

说明

状态

1

 

数据长度

压缩int,长度可以为1,2,4

 

其中数据长度描述的是列值的长度,单位为字节。列值部分存储的就是具体列的数据了,这一部分针对不同的存储内容,格式也不相同。列状态比较多:

状态

说明

FIELD_INITIAL

 列被初始化后的状态

FIELD_NULL

表示当前列值为null,而且列长度字段也不存储

FIELD_OVERFLOW

表示当前列已经溢出到其他页面中了

FIELD_NOT_NULLABLE

表示当前列已经不存在,例如alter语句将列drop

FIELD_EXTENSIBLE

该列是用户定义的数据类型

FIELD_TAGGED    

当且仅当状态FIELD_EXTENSIBLE的情况下,列状态才可以被设置为FIELD_TAGGED    

FIELD_FIXED

内部状态

上述这些列状态可以组合使用,也就是一个列可以同时处于上表中的多个状态。

未完待续。。。。。。






版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/kongxin163/article/details/77688011

智能推荐

河海和南邮计算机考研哪个好,南京邮电大学和河海大学哪个强?高考志愿应该选择哪一所?..._weixin_36369259的博客-程序员信息网

小编是主要负责江苏地区的老师,我对江苏省的高校还是相当了解的,南京邮电大学和河海大学相比较哪个强,在高考志愿填报的时候应该报考哪一个学校。我们来从这两个学校的整体实力上对比一下,河海大学是当地的一所重点大学,而南京邮电大学是双非大学里面相当不错的大学。但整体实力与河海大学相比较,还是差一点。首先,整体实力这个没有疑义,肯定是河海大学更强一些。河海大学作为一所重点大学,在江苏省内名气还是不错的,至于...

简单完整讲述Servlet生命周期_发呆小菜鸟的博客-程序员信息网

servlet生命周期过程1.加载web.xml文件——当前只去解析xml文件,知道servlet的存在,此时还没有去创建servlet。<!-- 声明servlet --> <servlet> <!-- servlet的别名 --> <servlet-name>first</servlet-name> <servlet-class>com.etime.servlet.FirstServlet</servlet-c

ubutun12.04解决不能启动xserver的问题_漂流的代码的博客-程序员信息网

ubutun12.04 不能进入桌面。最初的现象是:系统启动后,一直停在 ”ubuntu“的画面,不动了。解决方法:重新启动。在启动的同时,猛按方向键(我按的向下键),会进入到字符登陆界面。在字符登陆界面下登陆到系统,同时可以联网。在这个下面,启动sudo startx。会得到一堆错误,其中最后的错误是Fatel Error, No Scre

[EIP、EBP、ESP] --- [SS、SP、BP寄存器] --- 函数调用过程探究 ----汇编GDB--- mov指令_happylzs2008的博客-程序员信息网

山东省大学生科技节一道简单的PWN计算题https://www.k2zone.cn/?p=22561:计算机底层各种寄存器EIP & EBP & ESP ----1)https://blog.csdn.net/u012060033/article/details/792189092:函数栈&EIP、EBP、ES...

Linux内核源码的编译及安装_dwp1147170607的博客-程序员信息网

1 内核源码的编译先查看当前内核版本在内核ftp下载点下载与当前版本相近的内核源码,我选择了5.3.1的版本。在编译内核前,要根据目标内核的运行硬件环境对内核的编译选项进行配置,如make menuconfig等,为了简便,我这里在当前系统的config文件基础上进行编译。该config文件是在安装ubuntu是自动生成的,适配于本机硬件环境。本机的config文件在目录/boot/下...

javascript 中 typeof 的使用_托马斯小火车喷雾又喷烟,一直喷,喷喷喷.的博客-程序员信息网

数据类型Object。       typeof可以检测给定变量的数据类型。      对一个值使用typeof操作符可能返回下列某个字符串:string、number、boolean、undefined、function和object。<script type="text/javascript"> function testTypeOf() { var message = "hello"; alert(t

随便推点

Linux ALSA详解_自学Linux记录的博客-程序员信息网_alsa学习

Linux ALSA详解1. 介绍ALSA(即Advanced Linux Sound Architecture), 是目前Linux的主流音频体系结构, 提供了音频和MIDI的支持, 其架构图如下所示[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g0pGILrT-1628238732044)(C:%5CUsers%5CDELL%5CDesktop%5C%E7%AC%94%E8%AE%B0%5C%E6%B7%BB%E5%8A%A0%E8%AE%BE%E5%A4%87%E

Dll注入:Windows消息钩子注入_aijuzhou1959的博客-程序员信息网

SetWindowsHook()是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。钩子机制允许应用程序截获处理window消息或特定事件。HHOOK WINAPI SetWindowsHookEx(__in int idHook, \\钩子类型...

寄存器位设置_雲烟的博客-程序员信息网_设置寄存器的某几位

作为嵌入式工程师,一定要掌握寄存器的控制,想要了解基本的寄存器控制,最简单的方法就是使用单片机练手,51,stm0,stm8,MSP430等,与ARM7/9/11或A系列不同的是,不带系统的MCU说白了就是对各种寄存器进行配置,而无需理会内存映射、系统处理方式等复杂控制。假设存在两个8位寄存器GPIOCON1和GPIOCON2,分别需要对寄存器1的第7位置0,对寄存器2的第7位置1。操作如...

java泛型类的构造函数_java泛型,泛型类详解_怕还不清醒的博客-程序员信息网

之前给大家介绍了一下java泛型集合方面的内容,下面要给大家介绍的就是泛型类方面的知识,一起通过简单的文章来进行一下了解吧。泛型类除了能够定义泛型集合之外,还能够直接限定泛型类的类型参数。语法格式:publicclassclass_name{}在这当中,class_name表示类的名称,data_ type1等表示类型参数。Java泛型支持声明一个以上的类型参数,只要将类型用逗号隔开就可以了。...

OpenCV查找-绘制轮廓(cv2.findCountours函数,cv2.drawContours())_无止境x的博客-程序员信息网_findcountours函数

什么是轮廓轮廓可以简单认为成连续的点(连着边界)连在一起的曲线,具有相同的颜色或者灰度。轮廓在形状分析和物体的检测和识别中很有用。为了准确,要使用二值化图像。需要进行阀值化处理或者Canny边界检测。 查找轮廓的函数会修改原始图像。如果之后想继续使用原始图像,应该将原始图像储存到其他变量中。 在OpenCV中,查找轮廓就像在黑色背景中找白色物体。你应该记住,要找的物体应该是白色而背景应该是黑色。 如何在一个二值图像中查找轮廓。 函数cv2.findContours()有三个参数,第一个是输入

毕设教程:基于嵌入式Linux和Qt实现的视频监控系统(Arm/树莓派/jetson)_曾哥zengzr的博客-程序员信息网_基于linux的视频监控系统

本文章将教你做一个用嵌入式linux开发板和web端来实现的视频监控系统。代做/辅导:毕业设计/课程设计(QQ:914406940)知识点:嵌入式 Linux V4L2 socket Web node.js html QT硬件:开发板:ARM开发板、树莓派、jetson nano...等跑linux系统的开发板,连接一个摄像头;电脑:Web前端,可查看监控画面;功能介绍:开发板与电脑通过网络socket通信(网线、wifi均可),开发板获取摄像头的画面,将通过网络socke.

推荐文章

热门文章

相关标签