1.2 InnoDB页结构
2024-05-06 16:11:39 0 举报
AI智能生成
mysql Innodb存储引擎 数据页结构的相关学习知识整理
作者其他创作
大纲/内容
3. <b><font color="#4669ea">数据(</font></b><font><font color="#4669ea">索引</font><b><font color="#4669ea">)页 </font><font color="#000000">结构</font></b><font><font><font><font><b><font color="#4669ea"><br></font></b></font></font></font></font></font>
<font color="#4669ea"><span style="font-weight:normal;">User Records</span><font color="#4669ea"><span style="font-weight:normal;">、</span><font color="#4669ea"><span style="font-weight:normal;">Free Space </span></font></font></font><span style="font-weight:normal;">部分说明</span>
Page Directory (⻚目录) <font color="#000000">部分说明</font><br>
页内检索:单链表 的低效问题 <br>
我们已经知道,<font><font color="#4669ea">记录</font><font><font color="#000000">在</font><font><font color="#4669ea">⻚</font><font><font color="#000000">中是按照</font><font><font color="#4669ea">主键值</font><font><font color="#4669ea">由小到大</font><font><font color="#000000">顺序串联成一个单链表放在</font><font color="#4669ea"> </font><font><font color="#4669ea">UserRecords</font><font color="#000000"> 部分</font><font color="#000000">的。<br><br><font>如果我们想根据主键值查找⻚中的某条记录该咋办?</font><br><font>最笨的办法: 从 Infimum记录(最小记录)开始,沿着链表一直往后找,总有一天会找到(或者找不到)。</font><br><font>在找的时候还能投机取巧,因为链表中各个记录的值是按照从小到大顺序排列的,所以当链表的某个节点代表的记录的主键值大于你想要查找的主键值时,你就可以停止查找了。</font><br><br><font>这个方法在⻚中存储的记录数量比较少时也没啥问题,但如果一个⻚中存储了非常多的记录,</font><font><b>遍历操作对性能来说还是有损耗的</b>,所以说遍历查找这是一个笨办法。</font><font color="#e74f4c">(时间复杂度很显然是 `O(n)`)<br></font></font></font></font></font></font></font></font></font></font>
<b><font color="#e855a4">书籍目录</font></b><font color="#000000">的灵感引出</font><font color="#4669ea"><b>Page Directory</b></font>
<font color="#000000">设计InnoDB的大叔们自然不会用上面那种笨办法,他们从现实中的</font><b>书籍目录</b><font color="#000000">中找到了灵感。他们为页中的记录也制作了一个类似的目录。制作过程如下:</font><br><ul><li><font color="#000000">将所有正常的记录(包括页内的最大和最小记录,不包括标记为已删除的记录) 划分为几个</font><font color="#4669ea"><b>组</b> ;</font></li><li><font><font color="#4669ea">每个组的最后一条记录(也就是组内最大的那条记录)相当于“带头大哥”,组内其余的记录相当于“小弟”。</font><font><font color="#000000">“带头大哥”的记录头信息中的 </font><font><b><font color="#e855a4">n_owned</font><font color="#000000"> </font></b><span style="font-size:inherit;"><font color="#000000">属性表示该组内共有几条记录;</font></span></font></font></font></li><li><font><font><font><font><font><font color="#000000">将每个组内</font><font><font color="#000000">最后一条记录(也就是 “带头大哥”)在页面中的地址偏移量(就是该条记录与页面中第0个字节之间的距离)单独提取出来并且还<font>按主键顺序存储到靠近⻚尾的地方,这个地方就是所谓的</font></font><font> <font><font color="#e855a4">Page Directory,也就是`</font><font color="#4669ea"><b>⻚目录</b>`</font><font><font color="#000000">。</font><font><font color="#000000">⻚目录<span style="font-size:inherit;">中的这些</span></font><font><font color="#000000">地址偏移量<span style="font-size:inherit;">被称为 </span></font><b><font color="#4669ea">槽</font></b><font><font><span style="color:rgb(232, 85, 164); font-size:inherit;">(英文名:</span><b><font color="#4669ea">Slot</font></b><font><font><span style="font-size:inherit;"><font color="#e855a4">)</font><font color="#000000">,所以说,</font></span><b><font color="#000000">⻚目录其实就是由</font><font color="#4669ea">页内</font><font color="#000000">多个组中的</font><font color="#4669ea">带头大哥</font><font color="#000000">组成的</font></b><font><font><span style="font-size:inherit;">。</span></font></font></font></font></font></font></font></font></font></font></font></font></font></font></font></font></font></li></ul>
<b><font color="#4669ea">Page Directory</font></b><font color="#4669ea"> </font><font color="#000000">图例演示</font>
比方说现在的demo表中正常的记录共有6条,InnoDB会把它们分成两组,第一组中只有一个<b>最小记录</b>,第二组中是<b>剩余的5条记录</b>,2个组就对应着两个槽,<font color="#4669ea">每个槽中存放着每个组中最大的那条记录在页面中的地址偏移量</font>:<br>
接着,我们一口气又往表中添加了12条记录,现在⻚里边就一共有18条记录了(包括最小和最大记录),这些记录被分成了5个组: (图中只保留了用户记录头信息中的n_owned和next_record属性,也省略了各个记录之间的箭头!)<br>
<b><font color="#4669ea">Page Directory </font></b><font color="#000000">的使用</font>
<span style="font-weight:normal;">Page Header(⻚面头部) </span><span style="font-weight:normal;"><font color="#000000">部分各属性说明</font></span><br>
PAGE_N_DIR_SLOTS<br>
PAGE_HEAP_TOP
PAGE_N_HEAP<br>
PAGE_FREE<br>
PAGE_GARBAGE<br>
PAGE_LAST_INSERT<br>
PAGE_DIRECTION<br>
PAGE_N_DIRECTION<br>
PAGE_N_RECS<br>
PAGE_MAX_TRX_ID<br>
PAGE_LEVEL<br>
PAGE_INDEX_ID<br>
PAGE_BTR_SEG_LEAF<br>
PAGE_BTR_SEG_TOP<br>
<span style="font-weight:normal;">4. 通用页 结构</span>
<font color="#4669ea">File Header</font>(文件头部) 部分各属性说明
FIL_PAGE_SPACE_OR_CHKSUM
FIL_PAGE_OFFSET
FIL_PAGE_TYPE
FIL_PAGE_PREV、FIL_PAGE_NEXT
FIL_PAGE_LSN
FIL_PAGE_FILE_FLUSH_LSN
FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID
其他属性暂时用不到,等用到时再提~
<font color="#4669ea">File Trailer</font>(文件尾部) 部分
1. 为什么设计者要搞出个<b><font color="#4ccbcd">页</font></b><font color="#000000">的概念?</font>
首先你要明白的是: <br><ul><li>InnoDB存储引擎最基础且主要的一个特点是 “<font color="#4669ea"><b>表中的数据是存储到磁盘上的</b>”</font><font color="#000000">。(即便服务宕机重启后,数据也还是存在的,这点不像一些内存型数据库)</font></li><li><font color="#000000">尽管数据是存储到磁盘上的,</font><font><b>但数据的处理肯定是发生在内存中的</b><font color="#000000">。数据的读写操作<font>,自然也就涉及到</font></font><font> <b><font color="#4669ea">将磁盘中的数据加载到内存中</font></b><font color="#4669ea"> </font><font color="#000000">和</font><font> <b><font color="#4669ea">把内存中的内容刷新到磁盘上</font></b><font color="#4669ea"> </font><font><font color="#000000">的这两类操作。</font><br></font></font></font></font></li></ul>
当我们从表中获取记录时,InnoDB存储引擎是一条一条的把记录从磁盘上读出来么? <br>要知道 读写磁盘 和 内存读写 的速度相比,那可差了几个数量级嘞! <b><font color="#e74f4c">一次磁盘IO那么慢,你一次却只取一条数据......,那不慢死了</font></b><font color="#e74f4c">。<br></font>
2. InnoDB 多种不同的页类型
0 条评论
下一页