一. 简介

  1. Mysql是目前最为风行的关系型数据库管理系统, 具备体积小、速度快、开放源码等劣势。InnoDB是Mysql应用最宽泛的存储引擎, InnoDB进行了行锁设计, 反对MVCC, 提供一致性非锁定读。学习InnoDB数据页存储, 可能让咱们更加深刻的了解InnoDB的一些个性。
  2. 程序 = 数据结构 + 算法, 对于Mysql而言也是如此。因为数据长久化的须要, Mysql的数据不仅存储在内存中, 也会长久化到文件中, 存储构造如下图,

  • 从磁盘中, 咱们能够很容易的看到长久化的各个文件。
  • 磁盘中的文件须要加载到内存中能力被程序应用, 很显著, 不可能将所有磁盘文件都加载到内存, 当内存中的数据产生更改后, 也须要刷新到磁盘文件中, 什么时候刷新, 怎么刷新, 这些都是Mysql须要思考的问题, 然而这些内容不是本文的重点, 咱们这里稍加理解即可。
  • 本文的重点是学习数据页的存储, 这些数据页可能存在与零碎表空间, 独立表空间或者长期表空间。能够看到, 这些只是图中的一小部分。
  1. 学习之前, 咱们先思考几个问题,
  • 无论是内存存储还是磁盘存储, 都离不开内存治理, InnoDB是如何划分内存以及如何治理内存的?
  • InnoDB应用B+树存储咱们表中的数据, B+树索引节点以及叶子节点应该须要存储哪些数据? 又是怎么存储的?
  • 咱们在应用时, 创立了数据库, 数据表, 这些元数据是如何存储的, 查问某个表时, 如何依据元数据找到表的索引, 如何抉择索引, 抉择索引后, 如何定位到索引的根节点(root page)? 找到跟节点后, 又是如何一步步找到某个具体数据的?
  1. 阐明
  • Mysql版本: 8.0.12-debug
  • 存储引擎应用InnoDB
  • 咱们会用到xxd命令, 应用xxd(或者hexdump)能够以十六进制的形式查看文件。

二. InnoDB存储构造

InnoDB存储结构图如下所示, 咱们这里只做简要的介绍, 更多细节咱们将在后续的文章中再进行具体论述,

  1. 表空间(tablespace)能够认为是InnoDB存储引擎存储构造的最高层, 所有数据都在表空间中, 除了共享表空间外, 每个表能够创立独立表空间, 具体参数是由innodb_file_per_table参数决定, 表空间由各种段组成。
  2. 常见的段(segment)有数据段, 回滚段, 索引段。innodb中数据段就是B+树的叶子节点, 索引段就是B+树中的非叶子节点。
  3. 段是由区(extent)组成, 默认状况下区的大小是1MB, InnoDB默认页大小为16KB, 所以1个区是由16个间断页组成。
  4. innodb默认页(page)大小是16KB, 也能够通过innodb_page_size进行管制。
  5. innodb存储是面向行(row)的, 行的存储格局次要有compact、redundant、compressed、dynamic。

三. 数据页存储

3.1 独立表空间

通过innodb_file_per_table参数, 咱们能够为每个表都创立一个表空间, 这个就是这个表的独立表空间, 这个表的索引段, 数据段都会存储在这个独立表空间中, 然而Redo log, Undo log依然在各自的表空间中, 表空间存储如下图,

  1. 表空间的page 0是表空间的第一页, 存储了表空间的信息, 同时也用于治理前256个extent。page 16384类型为FIL_PAGE_TYPE_XDES也用于治理之后的256个extent, 以此类推, 每隔16384个页面都会须要一个FIL_PAGE_TYPE_XDES页面。
  2. page 1类型是FIL_PAGE_IBUF_BITMAP, 用于治理每个page(前256个extent的16384个页面)的change buffer(change buffer相干内容不是本文的重点, 感兴趣的读者能够查找相干材料)。与FIL_PAGE_TYPE_XDES相似, 每隔16384个页面都须要一个FIL_PAGE_IBUF_BITMAP页面。
  3. page 2类型为FIL_PAGE_INODE, 用于治理segment。
  4. page 3类型为FIL_PAGE_SDI, 存储Serialized Dictionary Information(SDI, 词典序列化信息), 存储了这个表空间的一些数据字典(Data Dictionary)信息。
  5. page 4个别就是这个表主键索引的root page。

3.2 页存储

InnoDB的页存储构造如下, 每页都是由3局部组成, File Header(38字节)、File Body、File Trailer(8字节), 不同页的File Body存储的内容不同,

  1. File Header
名称大小阐明
FIL_PAGE_SPACE_OR_CHKSUM4字节页的校验码
FIL_PAGE_OFFSET4字节表空间中页的便宜量
FIL_PAGE_PREV4字节上一页
FIL_PAGE_NEXT4字节下一页
FIL_PAGE_LSN8字节页面被最初批改时对应的日志序列地位
FIL_PAGE_TYPE2字节页面类型
FIL_PAGE_FILE_FLUSH_LSN8字节零碎表空间中有定义, 代表文件更新到的LSN
FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID4字节页面所属表空间id
  1. File Type
名称阐明
FIL_PAGE_TYPE_ALLOCATED0x0000未应用
FIL_PAGE_UNDO_LOG0x0002undo log
FIL_PAGE_INODE0x0003存储了段信息
FIL_PAGE_IBUF_FREE_LIST0x0004Insert Buffer闲暇列表
FIL_PAGE_IBUF_BITMAP0x0005Insert Buffer位图
FIL_PAGE_TYPE_SYS0x0006零碎页
FIL_PAGE_TYPE_TRX_SYS0x0007事务零碎数据
FIL_PAGE_TYPE_FSP_HDR0x0008表空间头部信息
FIL_PAGE_TYPE_XDES0x0009扩大形容页
FIL_PAGE_TYPE_BLOB0x000ABLOB页
FIL_PAGE_SDI0x45bdSDI索引页
FIL_PAGE_RTREE0x45beR-tree
FIL_PAGE_INDEX0x45bfB-tree

3.3 数据页

看完InnoDB页构造后, 咱们看下数据页的存储,

  1. Page Header
名称大小阐明
PAGE_N_DIR_SLOTS2字节page directory中slot的个数
PAGE_HEAP_TOP2字节堆中第一个记录指针
PAGE_N_HEAP2字节堆中记录数
PAGE_FREE2字节指向闲暇空间首地址
PAGE_GARBAGE2字节曾经删除的记录数
PAGE_LAST_INSERT2字节最初插入地位
PAGE_DIRECTION2字节最初插入方向
PAGE_N_DIRECTION2字节一个插入方向间断插入记录数
PAGE_N_RECS2字节这个页的记录总数
PAGE_MAX_TRX_ID8字节批改当前页的最大事务ID
PAGE_LEVEL2字节当前页在索引中的层, 叶子节点为0x00
PAGE_INDEX_ID8字节索引ID
PAGE_BTR_SEG_LEAF10字节非叶子节点所在段, 仅在B+树的root页中有定义
PAGE_BTR_SEG_TOP10字节数据页所在段, 仅在B+树的root页中有定义
  1. Infimun & Supermum

虚构记录, Infimum为13字节, Supermum也是13字节。具体存储内容, 咱们会在上面进行介绍。

  1. Page Directory
  • 页目录, 因为行记录在数据页中以链表的模式链接, 然而在查找记录时, 链表查找速度很慢, 为了减速记录查找, 创立页目录, 页目录能够用于二分查找。每个目录项占用2个字节, 从页尾部开始, 倒序存储。
  • 为了便于了解Page Directory, 咱们这里举一个例子, 如果表中存储了200条数据, 数据通过链表的形式进行链接, 咱们在查问时, 须要遍历整个链表能力找到数据, 这样无疑比较慢。咱们能够通过建设索引的形式, 放慢查找速度, 咱们能够将这200条记录的主键依照程序进行存储, InnoDB的Page Directory就是这个思路, 然而并不是存储了主键的值, 而是存储了对应记录的地位, 并且不是将每个行记录都存储在Page Directory中, 只是建设一个稠密索引。

3.4 innodb行存储

限于篇幅, 咱们这里次要介绍compact格局的行记录存储, 存储格局如下图,

  1. 从图中能够看出, 每个记录行至多占有5字节(记录头) + 主键长度 + 6字节(事务ID) + 7字节(回滚指针)
  2. 咱们须要留神记录头中的next_record字段, 这个字段占有16bit, 也就是2个字节, 通过这个字段, InnoDB将一个页中的所有记录以链表的形式链接到一起。

四. 实例解说

为了便于大家了解, 这部分咱们给出一些实例,

  1. 本节举例说明InnoDB的一个表是如何存储的, 次要介绍两种状况, 一种状况是表中数据很少, 另一种状况是表中数据比拟多, 一页曾经存储不了的状况。
  2. 表构造定义,
create table `t` (`id` int not null, primary key(`id`)) engine=InnoDB ROW_FORMAT=Compact;
  • 为了更容易了解, 咱们这里只创立了一个非常简单的表, 也只有一个主键索引。主键类型为int, 占用4个字节。
  • 创立表后, 能够在相应的目录下看到t.ibd文件, 这里我是在test数据库下创立的这个表, 所以也就在test目录下。
  • 从磁盘文件中, 咱们能够看到, t.ibd文件大小为112KB, 也就是7*16KB, 也就是7个page, 也就意味着, 创立表后, InnoDB默认初始化了7个page。
  • 咱们的表中没有变长字段, 主键长度为4字节, 所以单个记录的长度为5(记录头) + 4(主键ID) + 6(事务ID) + 7(回滚指针) = 22字节
  1. B+树示例

InnoDB数据存储是通过B+树组织的, 一个很简略的B+树如下所示,

  • B+树的性质有很多, 其增删查改操作较惯例的二叉树更简单一些, 感兴趣的能够查问相干材料, 这里有个基本概念即可。
  1. 后续如果没有非凡阐明, 表空间第一个页是page 0, 第二页是page 1, 以此类推。

4.1 单页存储

咱们首先看下当表中数据很少的时候, 数据是如何组织的, 具体操作步骤如下,

  1. 咱们向表中插入2条记录,
insert into t values (2);insert into t values (1);
  • 这里留神咱们先插入主键值为2的行记录, 再插入主键值为1的行记录。
  1. 通过xxd将t.ibd以16进制示意, 执行命令xxd t.idb t.txt, 也能够应用hexdump命令查看。
  2. 查看t.txt中的内容, 这里咱们查看page 4的数据
0010000: a76e 6043 0000 0004 ffff ffff ffff ffff  .n`C............0010010: 0000 0000 012e 6d9d 45bf 0000 0000 0000  ......m.E.......0010020: 0000 0000 0005 0002 00a4 8004 0000 0000  ................0010030: 0093 0001 0001 0002 0000 0000 0000 0000  ................0010040: 0000 0000 0000 0000 0091 0000 0005 0000  ................0010050: 0002 0272 0000 0005 0000 0002 01b2 0100  ...r............0010060: 0200 3069 6e66 696d 756d 0003 000b 0000  ..0infimum......0010070: 7375 7072 656d 756d 0000 10ff f380 0000  supremum........0010080: 0200 0000 001c 0481 0000 00fa 0110 0000  ................0010090: 18ff ea80 0000 0100 0000 001c 0582 0000  ................00100a0: 012c 0110 0000 0000 0000 0000 0000 0000  .,..............00100b0: 0000 0000 0000 0000 0000 0000 0000 0000  ............................0013fe0: 0000 0000 0000 0000 0000 0000 0000 0000  ................0013ff0: 0000 0000 0070 0063 a76e 6043 012e 6d9d  .....p.c.n`C..m.
  • 前38字节是文件头[0010000,0010026]
  • 之后56字节是数据页头部[0010027,001005d]
  • 之后的26字节是最小记录[001005e, 001006a], 最大记录[001006b, 0010077], 这里能够看到最小记录的n_owns值为1(只有本身1条记录), 最大记录的n_owns值为3(除了本身外, 还有咱们插入的两条记录)
  • 紧接着是第1条插入记录[0010078, 001008d]
0010070: .... .... .... .... 0000 10ff f380 00000010080: 0200 0000 001c 0481 0000 00fa 0110 ....
  • 最初是方才插入的第2条记录[001008e, 00100a3]
  • 对于int类型, innodb存储形式与惯例的形式不同, [0x00000000, 0x7fffffff]代表[-2147483648, -1], [0x80000000, 0xffffffff]代表[0, 21473647]。
  1. 存储构造如下图

  1. 这里示例下如何从最小记录查找到最大记录
  • 首先定位到最小记录的地位, 最小记录占有5字节(记录头) + 8字节(内容) = 13字节, 最小记录所在的地位为001005e, 依据最小记录的记录头信息, 能够计算出下一个记录所在位置001005e + 0030 = 001008e
  • 001008e是主键为1的记录所在位置, 接着计算下一个记录的地位001008e + ffea = 0010078, 这里须要留神的是, 加法运算时, 只保留前面4位的后果, 能够看到这个地位就是咱们第一次插入的主键为2的记录
  • 之后, 持续计算下一个记录所在位置, 0010078 + fff3 = 1006b, 这个就是最大记录所在的地位
  • 在查找某个具体的行记录时, 能够先利用page directory进行近似的二分查找, 之后再进行链表查找。
  1. page directory
  • 页尾部蕴含两个slots
0013ff0: 0000 0000 0070 0063 .... .... .... ....
  • 0063是第1个slot的地位, 相应的记录所在位置为0010063, 也就是最小记录。[001005e, 0010062]这个是最小记录的记录头, [0010063, 001006a]是最小记录的内容。
  • 0070是第2个slot的地位, 相应的记录所在位置为0010070, 这个是最大记录所在的内容开始地位。
  1. 小结
  • 能够看到, 从最小记录开始, 到最大记录完结, 数据依照主键程序以链表的形式进行链接。
  • 行数据的存储是依照插入的顺序存储的, 不是依照主键顺序存储, 数据删除后, 开释的空间能够复用, 对于复用局部的细节, 后续文章再进行具体介绍。

4.2 多页存储

在4.1的根底上, 咱们持续插入数据, 操作步骤如下,

  1. 咱们通过脚本向表中持续插入数据
<?php$servername = "localhost:8083";$username = "root";$password = "password";$dbname = "test";try {    $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);    for($i = 3; $i < 1000; $i++){        $sql = "INSERT INTO t VALUES (" . strval($i) . ")";        $conn->exec($sql);    }}catch(PDOException $e){    echo $sql . "<br>" . $e->getMessage();}$conn = null;?>
  • 之前表中曾经插入2条记录, 这里又插入997条记录, 所以表中当初一共999条记录, 主键id从1到999。
  • 单条记录须要占用22字节, 能够晓得, 此时, 单个数据页不能存储全副数据。
  1. 以16进制查看此时的t.ibd文件: xxd t.ibd t.txt
  2. 查看t.txt内容, 首先查看page 4的内容
0010000: df67 193d 0000 0004 ffff ffff ffff ffff  .g.=............0010010: 0000 0000 0132 5500 45bf 0000 0000 0000  .....2U.E.......0010020: 0000 0000 0005 0002 0092 8004 0000 0000  ................0010030: 008a 0002 0001 0002 0000 0000 0000 0000  ................0010040: 0001 0000 0000 0000 0091 0000 0005 0000  ................0010050: 0002 0272 0000 0005 0000 0002 01b2 0100  ...r............0010060: 0200 1a69 6e66 696d 756d 0003 000b 0000  ...infimum......0010070: 7375 7072 656d 756d 1000 1100 0d80 0000  supremum........0010080: 0100 0000 0500 0019 ffe6 8000 0153 0000  .............S..0010090: 0006 0000 0000 0000 0000 0000 0000 0000  ..............................0013fe0: 0000 0000 0000 0000 0000 0000 0000 0000  ................0013ff0: 0000 0000 0070 0063 df67 193d 0132 5500  .....p.c.g.=.2U.
  • 能够看到, 第5页, 目前只有大量内容, 因为此时第5页是索引页, 是B+树的根, 没有存储具体的数据, 只存储了主键索引。
  • File Header, Page Header, Infimum & Supremum跟之前根本相似, 这里就不再具体介绍。
  • 单个索引须要占用5字节(记录头) + 4字节(主键) + 4字节(记录所在页) = 13字节。
  • 第1个索引信息
0010070: .... .... .... .... 1000 1100 0d80 00000010080: 0100 0000 05.. .... .... .... .... ....

主键id为0x80000001, 也就是1, page no为0x00000005, 也就是page 5

  • 第2个索引信息
0010080: .... .... ..00 0019 ffe6 8000 0153 00000010090: 0006 .... .... .... .... .... .... ....

主键id为0x80000153, 也就是339, page no为0x00000006, 也就是page 6

  • 通过这两个索引信息, 能够晓得, page 5存储着主键id从1到338的数据, page 6存储着主键id从339到999的数据
  1. 查看page 5
0014000: e1c0 bb7a 0000 0005 ffff ffff 0000 0006  ...z............0014010: 0000 0000 0132 5500 45bf 0000 0000 0000  .....2U.E.......0014020: 0000 0000 0005 0056 3a90 82a6 1d89 1d0c  .......V:.......0014030: 0000 0005 0000 0152 0000 0000 0000 0000  .......R........0014040: 0000 0000 0000 0000 0091 0000 0000 0000  ................0014050: 0000 0000 0000 0000 0000 0000 0000 0100  ................0014060: 0200 1a69 6e66 696d 756d 0003 000b 0000  ...infimum......0014070: 7375 7072 656d 756d 0000 1000 1680 0000  supremum........0014080: 0100 0000 001c 0582 0000 012c 0110 0000  ...........,....0014090: 1800 1680 0000 0200 0000 001c 0481 0000  ................00140a0: 00fa 0110 0000 2000 1680 0000 0300 0000  ...... .......................0017e90: 0000 0000 0000 0000 0000 0000 0000 0000  ................0017ea0: 0000 0000 0070 3a27 39cf 3977 391f 38c7  .....p:'9.9w9.8.0017eb0: 386f 3817 37bf 3767 370f 36b7 365f 3607  8o8.7.7g7.6.6_6.0017ec0: 35af 3557 34ff 34a7 344f 33f7 339f 3347  5.5W4.4.4O3.3.3G0017ed0: 32ef 3297 323f 31e7 318f 3137 30df 3087  2.2.2?1.1.170.0.0017ee0: 302f 2fd7 2f7f 2f27 2ecf 2e77 2e1f 2dc7  0//././'...w..-.0017ef0: 2d6f 2d17 2cbf 2c67 2c0f 2bb7 2b5f 2b07  -o-.,.,g,.+.+_+.0017f00: 2aaf 2a57 29ff 29a7 294f 28f7 289f 2847  *.*W).).)O(.(.(G0017f10: 27ef 2797 273f 26e7 268f 2637 25df 2587  '.'.'?&.&.&7%.%.0017f20: 252f 24d7 247f 2427 23cf 2377 231f 22c7  %/$.$.$'#.#w#.".0017f30: 226f 2217 21bf 2167 210f 20b7 205f 2007  "o".!.!g!. . _ .0017f40: 1faf 1f57 1eff 1ea7 1e4f 1df7 0070 1d47  ...W.....O...p.G0017f50: 1cef 1c97 1c3f 1be7 1b8f 1b37 1adf 1a87  .....?.....7....0017f60: 1a2f 19d7 197f 1927 18cf 1877 181f 17c7  ./.....'...w....0017f70: 176f 1717 16bf 1667 160f 15b7 155f 1507  .o.....g....._..0017f80: 14af 1457 13ff 13a7 134f 12f7 129f 1247  ...W.....O.....G0017f90: 11ef 1197 113f 10e7 108f 1037 0fdf 0f87  .....?.....7....0017fa0: 0f2f 0ed7 0e7f 0e27 0dcf 0d77 0d1f 0cc7  ./.....'...w....0017fb0: 0c6f 0c17 0bbf 0b67 0b0f 0ab7 0a5f 0a07  .o.....g....._..0017fc0: 09af 0957 08ff 08a7 084f 07f7 079f 0747  ...W.....O.....G0017fd0: 06ef 0697 063f 05e7 058f 0537 04df 0487  .....?.....7....0017fe0: 042f 03d7 037f 0327 02cf 0277 021f 01c7  ./.....'...w....0017ff0: 016f 0117 00bf 0063 e1c0 bb7a 0132 5500  .o.....c...z.2U.
  • 留神页尾部蕴含page directory, slots的个数能够从page header中读取
  • File Header中的FIL_PAGE_NEXT字段, 值为0x00000006, 也就是page no为6的页。
  1. 查看page 6
0018000: 2ddb 788c 0000 0006 0000 0005 ffff ffff  -.x.............0018010: 0000 0000 0133 f431 45bf 0000 0000 0000  .....3.1E.......0018020: 0000 0000 0005 00a6 3946 8297 0000 0000  ........9F......0018030: 3935 0002 0142 0295 0000 0000 0000 0000  95...B..........0018040: 0000 0000 0000 0000 0091 0000 0000 0000  ................0018050: 0000 0000 0000 0000 0000 0000 0000 0100  ................0018060: 0200 1a69 6e66 696d 756d 0006 000b 0000  ...infimum......0018070: 7375 7072 656d 756d 0000 1000 1680 0001  supremum........0018080: 5300 0000 001d 6d81 0000 00a3 0110 0000  S.....m.......................001bea0: 0000 0000 0000 0000 0000 0000 0070 38c7  .............p8.001beb0: 386f 3817 37bf 3767 370f 36b7 365f 3607  8o8.7.7g7.6.6_6.001bec0: 35af 3557 34ff 34a7 344f 33f7 339f 3347  5.5W4.4.4O3.3.3G001bed0: 32ef 3297 323f 31e7 318f 3137 30df 3087  2.2.2?1.1.170.0.001bee0: 302f 2fd7 2f7f 2f27 2ecf 2e77 2e1f 2dc7  0//././'...w..-.001bef0: 2d6f 2d17 2cbf 2c67 2c0f 2bb7 2b5f 2b07  -o-.,.,g,.+.+_+.001bf00: 2aaf 2a57 29ff 29a7 294f 28f7 289f 2847  *.*W).).)O(.(.(G001bf10: 27ef 2797 273f 26e7 268f 2637 25df 2587  '.'.'?&.&.&7%.%.001bf20: 252f 24d7 247f 2427 23cf 2377 231f 22c7  %/$.$.$'#.#w#.".001bf30: 226f 2217 21bf 2167 210f 20b7 205f 2007  "o".!.!g!. . _ .001bf40: 1faf 1f57 1eff 1ea7 1e4f 1df7 1d9f 1d47  ...W.....O.....G001bf50: 1cef 1c97 1c3f 1be7 1b8f 1b37 1adf 1a87  .....?.....7....001bf60: 1a2f 19d7 197f 1927 18cf 1877 181f 17c7  ./.....'...w....001bf70: 176f 1717 16bf 1667 160f 15b7 155f 1507  .o.....g....._..001bf80: 14af 1457 13ff 13a7 134f 12f7 129f 1247  ...W.....O.....G001bf90: 11ef 1197 113f 10e7 108f 1037 0fdf 0f87  .....?.....7....001bfa0: 0f2f 0ed7 0e7f 0e27 0dcf 0d77 0d1f 0cc7  ./.....'...w....001bfb0: 0c6f 0c17 0bbf 0b67 0b0f 0ab7 0a5f 0a07  .o.....g....._..001bfc0: 09af 0957 08ff 08a7 084f 07f7 079f 0747  ...W.....O.....G001bfd0: 06ef 0697 063f 05e7 058f 0537 04df 0487  .....?.....7....001bfe0: 042f 03d7 037f 0327 02cf 0277 021f 01c7  ./.....'...w....001bff0: 016f 0117 00bf 0063 2ddb 788c 0133 f431  .o.....c-.x..3.1
  • 留神File Header中的FIL_PAGE_PREV字段, 值为0x00000005, 也就是page no为5的页。
  • 联合page 5能够看出, 叶子节点的两个页通过链表进行链接, 每个页内的数据通过记录头中的next_record字段进行链接。
  1. 存储结构图如下,

  1. 小结
  • 对于单页存储不了的状况, 须要进行页决裂, 此时B+树会有多层构造, 最低层为叶子节点, 存储了具体的数据, 下面是索引节点, 只存储主键以及下一层节点所在的页信息

五. 总结与思考

本文介绍了innodb的数据页存储, 以实例的形式解说了innodb存储引擎如何存储一个表中数据的。然而咱们依然有很多问题没有给出答案,

  1. 查找行记录时, 须要找到某个索引的root page, 这个信息是存储在哪里的?
  2. 咱们没有介绍段和区的相干内容, 这些在InnoDB数据存储时是如何应用的?
  3. 咱们查看数据时, 都是间接查看磁盘文件, 内存中的页与磁盘中的页有何区别, 内存中的脏页又是如何刷新到磁盘的?

InnoDB存储引擎较为简单, 不可能一次性将全部内容学会, 咱们无妨每次带入一个问题, 深刻寻找这个问题的答案, 对于这些问题, 我会在后续文章中再逐渐介绍。

六. 参考

  1. <<Mysql技术底细 InnoDB存储引擎>>
  2. 淘宝数据库内核月报