InnoDB是MySQL默认的存储引擎,也是MySQL使用最广泛的存储引擎,InnoDB存储数据的物理文件通常以ibd作为其文件名后缀,本文将结合源码,简单介绍ibd文件的整体结构。
innodb ibd文件以页为单位进行管理,默认情况下页大小为16k,ibd文件的大小必然为16k的整数倍。页的结构整体上可以分为页头、页身、页尾。其中页头占用固定的38字节,页尾占用固定的8字节,其余都为页身,ibd文件的每个页无一例外,都是这样的结构。如下图所示:
把页头(FIL Header)和页尾(FIL Trailer)的结构详细展开,见下图:
FIL Header结构:
checksum,4字节,存储该页的checksum值page numer,4字节,页号,也可以理解为页偏移,ibd文件中的每一个页都有一个唯一的页号previous page,4字节,上一个页的页号next page,4字节,下一个页的页号lsn for last page modification,8字节,存储lsnpage type,2字节,页类型flush lsn,8字节,存储lsnspace ID,4字节,表空间IDFIL Trailer结构:
checksum,4字节,该页的checksum值,理论上与FIL Header处理存储的checksum值一致lsn低32位,4字节页chcecksum值计算:
页头和页尾都有checksum值填充,innodb计算页的checksum值调用的是ut_crc32_hw或者ut_crc32_sw函数,ut_crc32_hw使用了硬件加速,需要cpu硬件支持,ut_crc32_sw为纯软件计算。这两个函数计算crc32的算法与通常使用的zlib.crc32开源算法并不一样。
innodb在计算一个页checksum时,把一个页分为两个部分,第一部分是第4到26字节,共22个字节,第二部分是第38到16376字节,共16338字节。使用ut_crc32_hw函数分别计算这两部分的crc32值,然后再把结果进行异或运算。源码如下:
字节序:
计算机存储数据分大端字节序和小端字节序,通常我们使用的硬件大多数是小端字节序,而innodb在存储数值时,使用大端字节序。比如页类型值为8,以2个字节存储,大端字节序和小端字节序对比如下:
大端字节序:0x0008小端字节序:0x0800页类型:
页类型定义在 innobase/include/fil0fil.h,页类型有很多种类,不同类型的页所代表的功能也不一样,比如一个ibd文件第一页其页类型为FIL_PAGE_TYPE_FSP_HDR,描述了表空间的元信息以及xdes entry信息。下面汇总所有页类型信息如下:
最后:
本文简单介绍了innodb ibd文件的页结构,页chcecksum计算方法,页类型以及innodb存储数值的字节序。本文涉及的MySQL源码版本为5.7.19,作者水平有限,如有错误,欢迎指正。