存储引擎原理拆解以及设计深度剖析
概述:
这个图片如果理解了。那就基本理解了索引page原理
接下来分别说一下页头,虚记录,记录堆,未分配空间,solt,页尾关于page的六部分
页头
记录页的控制信息,56字节,包括页的兄弟页指针和自身存储情况
虚记录
分为最大虚记录和最小虚记录,最大:比页内最大主键还大;最小:比页内最小主键还小
堆记录
行记录的存储区,分为有效记录和已删除记录两种
自由空间链表
已删除记录组成的链表
未分配空间
页面未使用的存储空间
页尾
占8字节 主要存储页面的校验信息
页内记录的维护
数据的维护无非查询增删 由于页的高效所以需要保证相对的顺序
顺序保证
正常的有物理有序和逻辑有序,由于物理有序的高额移动开销所以我们之说逻辑有序
通过以上我们可以看出每个页内都会组织一个有序的数据记录列表。
插入策略
自由空间链表:
如果数据刚好可以放下,直接在自由空间的合适位置写入。如果插入的数据过大,例如数据库写入一个文本或者大文本,或者常用的超长varchar 则需要用到未分配空间
未使用空间
页内查询
之所以建立各种链表则是需要尽兴快速查询。例如一个页存了N条数据,如果没有辅助链表则需要N的时间复杂度,明显不是我们想看到的,因此我们加入一个辅助表 solt 利用二分查找快速定位数显有N 到logn的检索时间复杂度的转变
关于页的概念大家有什么疑问可以留言区继续相互探讨学习
innodb的内存管理
概览
预分配内存空间:预先分配大量的未使用内存,以避免动态扩容带来的开销
数据以页为单位的加载:实现数据的小批量加载,比较每次都加载的io开销
数据内外存交换:更新落盘,保障数据的一致性和持久性
技术点
内存池
内存页面管理
页面映射
页面数据管理
数据淘汰
内存页都被使用
需要加载新内容
页面管理
空闲页
数据页
脏页
实际操作
通过上图我们可以很清晰的看到内存的维护过程,例如pagehash在页面属性发生变化的时候就会产生相应的变化 此处有三个page list队列需要维护
->buffer pool(预分配的内存池)
->page (buffer pool的最小单位)
->free list(空闲page组成的链表)
->flush list(脏页链表)
->page hash(维护内存page和文件page的映射关系)
->LRU 内存淘汰算法(此处为定制化多链表的LRU,可以参考redisLRU去理解)
此处分为三部分 LRU_NEW LRU_OLD 和Midpoint 我们可以看到LRU链表是以5/8为分界点,进行冷热数据的控制
我们可以看出lruold并不会通过一次访问直接从lru_old移动到lru_new的链表中 innodb中就利用的访问间隔去避免偶尔或者初始化的扫描导致热数据被覆盖的问题
此处还有技巧点是关于midpoint指针的移动,
MySQL设计思路:减少移动次数
两个重要参考:
1、freed_page_clock:Buffer Pool淘汰页数
2、LRU_new长度1/4 当前freed_page_clock - 上次移动到Header时freed_page_clock > LRU_new长度1/4
事务
这个问题大家既熟悉又陌生,特性并发和级别三个问题我们不再CV。
下次再分享给关于以下三个知识点
MVCC
undo log
redo log
实战中的那些问题
1 全表扫描对内存的影像 如何避免全表扫描带来的热数据被淘汰。