深入理解Mysql

发布于:2025-05-10 ⋅ 阅读:(13) ⋅ 点赞:(0)

BufferPool和Changebuffer是如何加快读写速度的?

BufferPool

在Mysql启动的时候 Mysql会申请连续的空间来存储BufferPool

每个页16kb 当控制块不足以存储信息的时候就会向后申请一个新的页

每个控制块都对应了一个缓存页 控制块占chunk的百分之5左右

LRU链表

Changebuffer

非唯一索引的变更并不会每次都直接进行磁盘IO 而是会先写入Changebuffer 这样如果需要读操作 就不用再去磁盘中io 减少了一次io 提高读写效率

总结

为了优化Mysql的读写效率 在内存中会有一块叫BufferPool 的空间 这里面会存储很多chunk

每个chunk 会存储许多控制块 每个控制块会对应一块缓存页

而为了维护缓存页的状态 就引入了Free链表Flush链表 这两个链表存储的都是缓存页对应的控制块

Free链表: 用来存储有那些控制块是空闲的 就是没有写入数据 (可用的)

Flush链表:用来存储BufferPool中哪些缓存页是有数据的

脏页:缓存页中和磁盘数据不一致的就被称为脏页 会定期刷盘来同步缓存

Changebuffer:修改数据的时候会先写入BufferPool中的Changebuffer 来提高读写效率

预读:每次读取磁盘的时候会认为这部分的内容可能会被连续访问 于是就连续读取一部分数据页到缓存中

LRU链表分为新生代和老年代 通过维护这两块区域 来实现冷热数据分离 避免全表扫描导致热点数据被覆盖

Mysql中的索引

索引下推

顾名思义 将索引从Server层下推到索引层去进行条件的过滤 避免多次回表

举个例子

比如模糊查询姓张的 age=18

那会先查询出姓张的 id=1/4 得到主键后回表根据1、4 在得到姓张的

再到Server层 对age=18进行过滤

索引下推

可以直接将条件下方到索引层

可以直接通过两个条件过滤数据行 然后回表查询

这样下来就减少了一次回表查询

页分裂的原因

假设每个Page页只能存放3条数据 当有一个主键为4的数据想要插入的时候

此时为了满足下一个数据页的主键大于上一个页的主键的约定:必须进行数据的移动 5右移 3插入

数据移动造成开销

聚簇索引

联合索引

自适应哈希索引

可以理解为索引的索引 这是Innodb自己创建的

当缓存中的数据经常被访问的时候 innodb会创建AHI 来提高索引的效率

通过O1 HashKV Key 存储热点数据 Value存储位置

在更新数据的时候BufferPool RedologBuffer 和三大日志会发生什么

当一个Update语句发生时:

1.Innodb会从磁盘中读取中对应的数据页到BufferPool 然后对BufferPool中的数据进行修改

2.同时将旧的数据写入Undolog方便数据进行回滚操作 以及配合MVCC进行多版本并发控制

3.然后将数据写入redologbuffer 为机器宕机后恢复数据做兜底操作

Redolog有自己的刷盘策略

1.延迟写 2.实时写 延时刷 3.实时写实时刷

当redolog刷盘后 此时如果宕机 但是事务还没提交 就可以通过redolog(记录的是物理数据)恢复

同时还会标记Prepare状态(两阶段提交)

4.同时也会写binlog (记录的是逻辑日志) 并且把redolog中的状态改为commit

Mysql架构

这也是innodb区别于其他存储引擎特有的支持事务的原因对吗 持久性 原子性


网站公告

今日签到

点亮在社区的每一天
去签到