mysql

插入连续的数据在一个页里,每次查询都有一次与磁盘的io,比较耗时,而我们拿数据是从内存中拿,为了减少磁盘与内存的交互,innodb采取页的方式存储数据

 

 

表空间  磁盘上文件的一个映射,定义数据位置信息的一块空间

infimum 存在表中的任意数据都没有我小   supermum 存在表中的任意数据都没有我大

 

 

从free space中申请空间,free space越来越小,user records越来越大,最后数据满了,free space没有空间了

 

表中没有主键也没有唯一约束的时候,roow_id可以保证一条数据的唯一性

记录:存储在页中插入的一条数据

 

 

 

 

看到这里,大家可能会有疑问:我删除了一条记录,难道它还存在于页中吗,或者说还是存放在磁盘上吗?答案是:没有被删除,也还存放磁盘上。因为当删除记录时,存储引擎是不会立即删除它们的,因为移除它们之后,还需要把其它的记录重新排列,这样就会造成性能损耗,所以只是打上删除标签而已。当然了,都把这些记录打上删除的标签了,肯定不能和那些正常记录在一个链表中了,就会形成一个所谓的垃圾链表,在这个链表中的记录占用的空间称之为所谓的可重用空间,之后如果有新记录插入到表中的话,可能把这些被删除的记录占用的存储空间覆盖掉。

 

 

 

 

 

 

 

删除操作:deleted_flag置为1,next_record指向下下一条的记录,n_owned条数减1     如果插入一条删除的记录,在垃圾链表的空间没有被覆盖的情况下,插入的顺序也是deleted_flag --0   next_record--下一条记录  n_owned---+1

 

 

如果是单页,可以先用二分法找到对应的槽,在遍历next_record

 

 

 

 type_record 为1  非叶子节点的目录项    非叶子节点:主键和页号

 

 可以通过回表查找数据,先通过二级索引找到主键,再找到具体的数据  叶子结点由c2+c1组成   非叶子节点 由c2+page组成

 

 

 

 

 

 

 

控制页:存储了控制缓存页的参数

innodb_buffer_pool_size  默认buffer pool是128M 多出的50%是存控制块的

哈希表:key:表空间+页号

value:控制块 ,由控制块控制缓存页的状态,是否被修改,是否需要同步

 

 

 

 

 

将被修改的脏页放到flush链表中,在某一时刻刷新到磁盘

不会出现控制块同时在free链表和flush链表的情况,flush链表的缓存页一定有数据,free链表的缓存页没有

 

 

LRU ҁLeast Recently Used҂

如果buffer pool没有页,从磁盘中加载到lru链表的头部,如果链表中有页,就把这个页放到lru链表的头部

 

预读 读取当前请求的时候,innodb会默认后面读取的页面也在这个请求的附近,就会提前将后面的那些请求提前读取出来   线性预读  如果顺序访问了某个区(共64个页面)的页面(超过56个页面)就会把下一个区的所有页面全部加载进来    随机预读  没有顺序的去读,如果这个区有连续的13个页面被加载,就会把这个区的所有页面都加载

解决:innodb在初次从磁盘向bp中加载数据的时候只会往old中加载,那么预读只会加载old中的数据

全表扫描  会把lru链表的所有数据都冲刷掉  一个页16kb,全表扫描一个页的时间在1m内

解决:某一时刻间隔内,第一次全表扫描从old中读取数据与第二次从old中读取数据的时间间隔<1000ms,则数据不会从old刷新到young区

 

 

 

 底层以chunk为单位向操作系统申请内存空间

 

 

 

posted @ 2021-07-12 23:10  悬崖听风098  阅读(32)  评论(0编辑  收藏  举报