美文网首页
MySQL-Innodb表空间

MySQL-Innodb表空间

作者: 多血 | 来源:发表于2019-12-20 22:19 被阅读0次

    逻辑结构

    所有的数据都被逻辑的存放在一个空间中,称之为表空间。表空间又由段(Segment)=>区(Extent)=>页(Page)组成。逻辑存储结构大致如下图


    image.png

    逻辑结构在IBD文件中如何描述

    表空间下一级称为Segment。Segment与数据库中的索引相映射。Innodb引擎内,每个索引(包括聚簇索引)对应两个Segment:管理叶子节点的Segment和管理非叶子节点的segment。Innodb内部使用Inode来描述segment(存于Inode页中的,IBD中第一个Inode页为IBD文件的第三个页)。
    Segment的下一级是Extent,Extent代表一组连续的page,默认为64个page,大小1MB。Extent的作用是提高page分配效率,批量分配在效率上总是优于离散、单一的Page分配,另外在数据连续性方面也更佳,Innodb内部使用XDES来描述Extent(存于Extent Descriptor页中,第一个Extent Descriptor为IDB文件的第一个页)。
    Page则是表空间数据存储的基本单位。
    IBD概览图如下,第一个Page中存放了Filespace Header和Extent Descriptor,第三个Page中存放了Inode。


    image.png

    站在一个索引的角度来看,结构如下图,一个Index有2个Segment,这两个Segment信息存在于这个Index 的root Page中,即Page 3中,描述这两个Segment的Inode存放在Page2中,Inode中包含Frag Array(指向每个Segment初始的32个Page)以及一些链表,如Full List,Not Full List,Free List,链表元素指向Page 0中的Xdes或后面的Xdes(由于单个Edes page只能描述256个extent,因此,每隔256个Extent(16384个page)便需要一个Xdes page)。Xdes中的页存放这个Index具体的数据。


    image.png

    元数据页

    FSP_HDR PAGE

    数据文件的第一个Page类型为FIL_PAGE_TYPE_FSP_HDR,在创建一个新的表空间时进行初始化(fsp_header_init),该Page除了页的常规头部和尾部外,包括FSP HEADER和256个Xdes。如下图

    image.png
    FSP HEADER中包含文件的基本元信息,通过FREE、FREE_FRAG等LIST管理着整个IBD文件的Extent,通过FULL_INDES、FREE_INODES等LIST管理着整个IBD文件的Inode页,如下图
    image.png
    image.png
    Xdes包含一个Extent的信息,如下图
    用bitmap表示页(分配页用遍历的方法)。
    image.png
    image.png

    IBUG_BITMAP PAGE

    IBUF_BITMAP Page Overview.png
    IBUF_BITMAP Entry.png

    INODE PAGE

    表空间文件的第3个Page的类型为FIL_PAGE_INODE,存储Inode,管理表空间的Segment。每个Inode对应一个Segment。每个Inode Page默认存储FSP_SEG_INODES_PER_PAGE(85)个Inode。每个索引使用2个segment,分别用于管理叶子节点和非叶子节点。如下图


    image.png
    image.png

    Inode管理着Segment的信息,通过FREE、NOT FULL等LIST管理着分配给自身的Extent。如下图


    image.png
    image.png
    结合上面的了解,这个IBD文件的连接方式如下图,Page 0中FSP HEADER中元素连接着IBD文件中的Inode页以及Extent(Xdes Entry),Inode Page中的Inode中元素连接着自身的Extent以及其他Inode 页。
    image.png

    作用

    上文中结构的作用主要是为了管理Extent和Page的申请、分配和回收。

    磁盘链表

    上文中多个List(如指向Xdex或Inode Page的)都是以磁盘链表形式组织的。
    Innodb的磁盘链表主要是用来连接存储在磁盘上的对象。链表每项并非基于内存指针的,而是基于对象在磁盘中的位置(page no + offset)来描述。

    typedef struct fil_addr_struct
    {
     ulint  page;        /*page在space中的编号*/
     ulint  boffset;     /*page中的字节偏移量,在内存中使用2字节表示*/
    }fil_addr_t;
    
    typedef byte flst_node_t;
    typedef byte flst_base_node_t;
    /* The physical size of a list base node in bytes */
    constexpr ulint FLST_BASE_NODE_SIZE = 4 + 2 * FIL_ADDR_SIZE;
    /* The physical size of a list node in bytes */
    constexpr ulint FLST_NODE_SIZE = 2 * FIL_ADDR_SIZE;
    

    flst_node_t代表链表上的一个节点,其大小为12字节,其中前6字节(page:4 boffset:2)表示链表中前一个节点的fil_addr_t信息,后6个字节表示链表中下一个节点的fil_addr_t信息。
    flst_base_node_t则用于描述链表的整体信息,包括:

    链表节点个数FLST_LEN(4字节)
    链表首节点的fil_addr_t (6字节)
    链表尾节点的fil_addr_t(6字节)
    

    磁盘链表结构关系

    image.png

    每个要连接在该链表上的对象中均需要预留12个字节来记录前后节点位置。例如,xdes和inode page中均有该12字节的预留。

    https://blog.csdn.net/yuanrxdu/article/details/41925279
    https://zhuanlan.zhihu.com/p/86394885
    http://mysql.taobao.org/monthly/2016/02/01/

    相关文章

      网友评论

          本文标题:MySQL-Innodb表空间

          本文链接:https://www.haomeiwen.com/subject/jwhwnctx.html