上一篇博客回顾:

    1:数据库拥有众多的储存引擎,现在主要使用的是Inoodb,这个储存引擎有Compact,Redundant,Dynamic,Compressed四种行格式

    2:Compact行格式的结构分为变长数据长度列表,NULL值列表,记录头信息,真是数据储存

    3:变长数据长度列表储存的是变长数据类型数据的字节数逆顺序,空值列不储存,NULL值列表储存非主键和没有被NOT  NULL 修饰的列,二进制位逆顺序进行储存。

    4:记录头信息包括了偏移量,槽数量,本组数据量,是否被删除,数据类型,是不是B+树子节点等等信息。

    5:真实数据会有三个三个虚拟列,ROW_ID(没有主键的时候自动生成),ROLL_POINTER,TRANSACTION_ID(事务管理ID)

    5:行溢出数据的处理Compact行格式是使用最后记录下一页地址的方式,然而Redundant和Compressed是采用整页记录数据页地址的方式,后两者的Compressed采用压缩算法。

    6:对于char相似类型的数据来说,如果我们采用可变的字符集进行操作也是会在可变长度数据列表里面进行储存的。

    7:对于可变数据长度列表储存的占用字节为1或者2,NULL值用二进制位,记录头信息在Compact行格式占用5个字节,Redundant占用6字节。一页空间16kb。

页储存结构:

    我们都知道的是数据库一个页的储存空间是16kb,那么这16kb的储存空间是怎么进行分配,数据在这个储存空间里是怎么样的一个格式呢?对于这些数据数据库都进行了什么操作?这就是我们今天需要进行学习的内容。

    

    可能按照顺序来说的话不是太方便进行讲诉,而且看起来可能也不会效果太好,所以我们一点一点根据功能的划分进行区分。

    User Records:

      这个区域对我们插入的数据进行保存,需要说明的是原本这一块是不存在的,当我们插入数据的时候这块区域才会被划分出来。并且是从Free Space进行的划分。当我们的Free Space区域所有的空间都变成了UserRecords,那么这时候就是需要重新开辟一个储存页的时间了。

      那么当我们把数据放在这个区域里面的时候,是不是就是说没有一点规则,随便进行摆放,其实想一想就知道了,当我们数据过于庞大的时候,我们随便摆放,查找会是多么的痛苦。所以接下来在我们知道数据保存在那个位置以后我们需要弄清楚的是数据在User Records里的情况。在这里我们假设插入了四条我们自己的记录:

      两个虚拟的数据:我们可以看到下图所示,我们插入了四条记录的时候,但是在我们这个页中存在的是六条记录,也就是两条我们说的每个页中都会存在的虚拟记录:最大记录和最小记录。他们都存infumum_supremum里面,因为不是我们自己插入的记录所以是不在User_Record里面.最小记录默认在开始,最大记录在最末尾结束  

        

      接下来我们再根据这六条记录描述一些问题:

          1:我们在每条数据的记录头里面提到的Record_Type标记的是这条数据的类型,当时我们说的是有0普通数据,1叶子节点数据,2最小数据,3最大数据。我们可以看到的是上边最大和          最小数据分别是3和2, 我们自己插入数据的记录头信息在Record_type这里都是0.

          2:我们在记录头信息里面还可以看到的是delete_mask这个数据,表示的是数据是否被删除,0表示没有,1表示已经被删除,所以上边的数据都是0

          3:heap_no我们讲过是标记该数据在页中的位置,我们可以看到插入数据分别是2,3,4,5。那么0和1去哪了,别着急,请看看最小记录和最大记录的该数据,是不是分别为0和1。我          们插入的数据都会从2开始计数,虚拟数据会占用默认的0和1的位置。

          4:插入数据的排列是否就是数据插入的顺序,那显然是不可能的,你没想错,数据会根据大小进行排列,那么数据用什么进行大小的排列?显然就是主键进行比较。

          5:next_record记录的就是相对于本条数据,下一条数据的地址偏移量,就是通过这条数据往下查找这么多字节就可以找到下一条数据,没错。他就是使用的链表进行链接的。如下图:

          

          6:如果一条数据被删除,也就是它的delete_mask被标记为了1,那么这个会怎么进行改变?就是和链表一致,进行链接的切断就可以了。

             

          7:我们在进行数据查找的时候就是这么一条接一条的进行查找么?从最小记录开始根据next_record查找?那必然是耗时的一个活,显然是不可能的,所以在就出现了分组这个概念。

            

          

          

        分组:

          我们可以看到的是六条数据分成了两组,首先是最小的虚拟数据独自一组,然后剩下的五个数据再分成一组。在这里需要知道的就是MySql数据库在每个页中进行数据分组的时候默认的        最小数据是第一组,它拥有一条数据,就是最小数据,不能在插入其他数据。最大数据是第二组,我们在进行数据插入的时候都是先插入最大数据组,当最大数据组满足的时候进行分裂,形        成普通的分组,然后再进来的数据又插入最大数据组,如此循环往复,完成数据的分组。

        槽:

          我们还可以看到的是在分组的图里面出现了两个奇奇怪怪的东西,槽,我们上一篇文章页诉说过这个玩意儿。每个分组数据的相对于页的地址偏移量就是一个槽数据,一个分组有一个         槽,槽存在的位置就是页信息的Page Directory。在这里我需要强调的是在记录头信息中有个地址偏移量next_record,这个偏移量是本条数据相对于下一条数据位置,然后槽中的偏移量是分        组最后一条数据相对于页的偏移量。

        寻找:

          有了分组以后,我们在进行数据查找的时候就是根据二分法确定对应数据所在的槽位置,然后在使用记录头信息的next_record一条条进行查找。

        n_owned:

          这个数据我们在记录头信息中一直看到,其实在这里就可以结束这个数据了。它表示的是该分组有多少条数据,存在于分组的最后一条信息中。我们可以看到的是每个分组的前面的数据        n_owned都是0,只有在最后一条数据上它才有值。

page_header

  上边我们通过数据的方式介绍了User_Records,infumum_supremum,page_directory,Free spce这四块空间的使用情况,接下来需要进行解释的就是page_header,file_header,file tailer这三块空间。

   首先说的就是page_header,这个地方储存的就是数据的一些信息:

    

PAGE_N_DIR_SLOTS 2字节 在页目录中的槽数量
PAGE_HEAP_TOP 2字节 第一个记录的地址
PAGE_N_HEAP 2字节 本页中的记录的数量(包括最小和最大记录以及标记为删除的记录)
PAGE_FREE 2字节 指向可重用空间的地址(就是标记为删除的记录地址)
PAGE_GARBAGE 2字节 已删除的字节数,行记录结构中delete_flag为1的记录大小总数
PAGE_LAST_INSERT 2字节 最后插入记录的位置
PAGE_DIRECTION 2字节 最后插入的方向
PAGE_N_DIRECTION 2字节 一个方向连续插入的记录数量
PAGE_N_RECS 2字节 该页中记录的数量(不包括最小和最大记录以及被标记为删除的记录)
PAGE_MAX_TRX_ID 8字节 修改当前页的最大事务ID,该值仅在二级索引中定义
PAGE_LEVEL 2字节 当前页在索引树中的位置,高度
PAGE_INDEX_ID 8字节 索引ID,表示当前页属于哪个索引
PAGE_BTR 10字节 非叶节点所在段的segment header,仅在B+树的Root页定义
PAGE_LEVEL 10字节 B+树所在段的segment header,仅在B+树的Root页定义

      在上边我们需要说的就是PAGE_DIRECTION和PAGE_N_RECS这两个数据第一个指的是最后插入的方向,相对于上一条数据来说,我们新插入的比他大,就在右边,反之则在左边,这就是方        向。当我们插入数据连续的都在右边或者是都在左边的时候就会记录下数量。当然如果改变方向的话这个数据会被清空从零开始计数。

File_Header:

  上边讲的page_header就是对页储存记录的描述,那么这里的File_Header就是对页信息的描述:

   

名称 占用空间大小 描述
FIL_PAGE_SPACE_OR_CHKSUM 4字节 页的校验和(checksum值)
FIL_PAGE_OFFSET 4字节 页号
FIL_PAGE_PREV 4字节 上一个页的页号
FIL_PAGE_NEXT 4字节 下一个页的页号
FIL_PAGE_LSN 8字节 最后被修改的日志序列位置(英文名是:Log Sequence Number)
FIL_PAGE_TYPE 2字节 该页的类型
FIL_PAGE_FILE_FLUSH_LSN 8字节 仅在系统表空间的一个页中定义,代表文件至少被更新到了该LSN值,独立表空间中都是0
FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID 4字节 页属于哪个表空间

  我们可以看到三个值,一个记录的是这个页的页号,上一个页,下一个页。针对上面我们讲的一个页中的数据是采用单向链表的形式进行连接,那么我们可以想到的是数据库中的页是采用的双向链表。

    

   我们在上面还可以看到的是 FIL_PAGE_TYPE这个值,描述的是这个页的类型,显然我们数据库不可能就只有一种数据页,上面我们讲的储存真实数据页就是数据页。FIL_PAGE_INDEX,也就是我们提到的   B+树叶子节点。

   

名称 十六进制 描述
FIL_PAGE_ALLOCATED 0x0000 最新分配,还没使用
FIL_PAGE_UNDO_LOG 0x0002 Undo Log页
FIL_PAGE_INODE 0x0003 段信息的节点
FIL_PAGE_IBUUF_FRE_LIST 0x0004 Insert Buffer空闲列表
FIL_PAGE_IBUF_BITMAP 0x0005 Insert Buffer位图
FIL_PAGE_TYPE_SYS 0x0006 系统页
FIL_PAGE_TYPE_TRX_SYS 0x0007 事务系统数据
FIL_PAGE_TYPE_FSP_HDR 0x0008 File Space Header
FIL_PAGE_TYPE_XDES 0x0009 扩展描述页
FIL_PAGE_TYPE_BLOB 0x000A BLOB页
FIL_PAGE_INDEX 0x45BF B+树的子节点

 

 File Trailer

  这玩意需要和上面File header中的FIL_PAGE_SPACE_OR_CHKSUM这个属性系统校验和一起说。我们都知道的是页是一块16kb的储存空间,不管是内存刷新到数据库取用都是一次操作16kb。那么如果在中途产生停电等不可抗拒的因素,这时候这里就起作用了。File Header位于页的开始,它会计算一个校验和,这个校验和你可以这么理解,当我们需要一个很复杂的字符串的时候,往往会将它按照一定的算法进行计算出一个整数值,当和其它字符串进行比较的时候就用这个值。所以校验和也是这个道理,File Trailer是位于页尾部的,他也会储存一个校验和。如果数据不完整,那么两个校验和不可能一致,那么就可以判定这个数据页是损坏的。

       

      

MySQL数据库Innodb储存引擎----储存页的结构的更多相关文章

  1. MySQL数据库InnoDB存储引擎多版本控制(MVCC)实现原理分析

    文/何登成 导读:   来自网易研究院的MySQL内核技术研究人何登成,把MySQL数据库InnoDB存储引擎的多版本控制(简称:MVCC)实现原理,做了深入的研究与详细的文字图表分析,方便大家理解I ...

  2. MySQL数据库InnoDB存储引擎中的锁机制

    MySQL数据库InnoDB存储引擎中的锁机制    http://www.uml.org.cn/sjjm/201205302.asp   00 – 基本概念 当并发事务同时访问一个资源的时候,有可能 ...

  3. MySQL数据库InnoDB存储引擎

    MySQL数据库InnoDB存储引擎Log漫游  http://blog.163.com/zihuan_xuan/blog/static/1287942432012366293667/

  4. 关于MySql 数据库InnoDB存储引擎介绍

    熟悉MySQL的人,都知道InnoDB存储引擎,如大家所知,Redo Log是innodb的核心事务日志之一,innodb写入Redo Log后就会提交事务,而非写入到Datafile.之后innod ...

  5. MySQL数据库InnoDB存储引擎中的锁机制(转载)

    http://www.uml.org.cn/sjjm/201205302.asp 00 – 基本概念 当并发事务同时访问一个资源的时候,有可能导致数据不一致.因此需要一种致机制来将访问顺序化. 锁就是 ...

  6. 1009MySQL数据库InnoDB存储引擎Log漫游

    00 – Undo Log Undo Log 是为了实现事务的原子性,在MySQL数据库InnoDB存储引擎中,还用Undo Log来实现多版本并发控制(简称:MVCC). - 事务的原子性(Atom ...

  7. 0728MySQL数据库InnoDB存储引擎重做日志漫游REDOLOG,UNDOLOG

    转自http://www.mysqlops.com/2012/04/06/innodb-log1.html 00 – Undo LogUndo Log 是为了实现事务的原子性,在MySQL数据库Inn ...

  8. MySQL数据库InnoDB引擎下服务器断电数据恢复

    说明: 线上的一台MySQL数据库服务器突然断电,造成系统故障无法启动,重新安装系统后,找到之前的MySQL数据库文件夹. 问题: 通过复制文件的方式对之前的MySQL数据库进行恢复,发现在程序调用时 ...

  9. MySQL数据库MyISAM存储引擎转为Innodb

    MySQL数据库MyISAM存储引擎转为Innodb  之前公司的数据库存储引擎全部为MyISAM,数据量和访问量都不是很大,所以一直都没什么问题.但是最近出现了MySQL数据表经常被锁的情况,直接导 ...

  10. MySql中innodb存储引擎事务日志详解

    分析下MySql中innodb存储引擎是如何通过日志来实现事务的? Mysql会最大程度的使用缓存机制来提高数据库的访问效率,但是万一数据库发生断电,因为缓存的数据没有写入磁盘,导致缓存在内存中的数据 ...

随机推荐

  1. PNotes – 目前最优秀的桌面便签软件 - imsoft.cnblogs

    Pnotes: 下载链接: http://pan.baidu.com/s/1o6FK4SM 密码: n7il 便携版,包含中文语音包,包含十几种合适的皮肤. 更多信息:小众软件 http://www. ...

  2. POJ 2407:Relatives(欧拉函数模板)

    Relatives AC代码 Relatives Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16186   Accept ...

  3. 大家一起做训练 第一场 A Next Test

    题目来源:CodeForce #27 A 题目的意思简而言之就是要你输出一个没有出现过的最小的正整数. 题意如此简单明了,做法也很明了. 直接读入所有的数,然后排个序,设置个变量从1开始,出现过+1, ...

  4. (4)logging(日志模块)

    日志分成几个常用的级别 debug 10 代表程序调试过程中的信息 info 20 代表普通日志信息,用户的访问等等 warning 30 警告日志,有可能出错,但是目前还没出错的 error 40 ...

  5. 结构体:HASH表模板

    这种 HASHMAP 就是一个链式前向星的表: 其中: init 函数:hashmap 创建初始化: check 函数:寻找 hash 表中是否有需要查找的值,若有则返回 1 ,否则返回 0 :遍历方 ...

  6. Anaconda+Tensorflow环境安装与配置

    转载请注明出处:http://www.cnblogs.com/willnote/p/6746499.html Anaconda安装 在清华大学 TUNA 镜像源选择对应的操作系统与所需的Python版 ...

  7. Html页面Dom对象之Element

    HTML DOM Element 对象 HTML DOM 节点 在 HTML DOM (文档对象模型)中,每个部分都是节点: 文档本身是文档节点 所有 HTML 元素是元素节点 所有 HTML 属性是 ...

  8. knowledge 开源知识管理系统

    knowledge 是一个不错的知识管理系统,基于markdown 我们可以方便的进行知识的标签 以及展示 使用docker-compose 运行 环境准备 docker-compose 文件 ver ...

  9. 【Android界面实现】AppWidght全面学习之电量监控小部件的实现具体解释

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/bz419927089/article/details/35791047 前几天翻看之前下载的各种资料 ...

  10. java打jar包的几种方式详解

    经常会头疼于一个jar包是如何制作的,包括maven的打包方式,springboot的打jar包的原理,jar包稍稍有错误就会完全无法运行.在网上折腾了很久终于有些思路和步骤,在这里做个笔记 本文目录 ...