逻辑结构
所有的数据都被逻辑的存放在一个空间中,称之为表空间。表空间又由段(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。如下图
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.pngIBUF_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/
网友评论