Mysql存储引擎原理

Mysql的数据是如何组织的呢?
当然是page,也就是说mysql以页为单位进行内外存交换。

一、 MySQL记录存储(页为单位)

在这里插入图片描述

页头
记录页面的控制信息,共占56字节,包括页的左右兄弟页面指针、页面空间使用情况等。

虚记录
最大虚记录:比页内最大主键还大
最小虚记录:比页内最小主键还小
(作用:比如说我们要查看一个记录是否在这个页面里,就要看这个记录是否在最大最小虚记录范围内)

记录堆
行记录存储区,分为有效记录和已删除记录两种

自由空间链表
已删除记录组成的链表
(重复利用空间)

未分配空间
页面未使用的存储空间;

Slot区

页尾
页面最后部分,占8个字节,主要存储页面的校验信息;

页内记录维护

聚簇索引

1、顺序保证

  1. 物理有序(利于查询,不利于插入删除)在这里插入图片描述

2. 逻辑有序(插入删除性能高,查询效率低) 默认
在这里插入图片描述
所以mysql是像下图所示这样子有序的组织数据的。
在这里插入图片描述

2、插入策略

  1. 自由空间链表(优先利用自由空间链表)
  2. 未使用空间
    在这里插入图片描述

3、页内查询

  1. 遍历

  2. 二分查找(数据不一样大,不能用二分)

在这里插入图片描述
利用槽位做二分,实现近似的二分查找,近似于跳表

二、 MySQL InnoDB存储引擎内存管理

预分配内存空间

  1. 内存池

数据以页为单位加载 (减少io访问次数)

内存页面管理

  1. 页面映射(记录哪块磁盘上的数据加载到哪块内存上了)
  2. 页面数据管理

数据内外存交换

数据淘汰

  1. 内存页耗尽
  2. 需要加载新数据

在这里插入图片描述

页面管理
空闲页
数据页
脏页(需刷回磁盘)

页面淘汰
LRU(淘汰冷数据)

在这里插入图片描述
某时刻状态->访问P2->访问新页P7

全表扫描对内存的影响?
可能会把内存中的热数据淘汰掉(比如说对一个几乎没有访问量的表进行全表扫描)

所以mysql不是单纯的利用LRU算法

解决问题:如何避免热数据被淘汰?

解决方案:
访问时间 + 频率(redis)
两个LRU表

Mysql的解决方案

在这里插入图片描述
MySQL内存管理—LRU
在这里插入图片描述

页面装载

磁盘数据到内存
在这里插入图片描述

在这里插入图片描述
没有空闲页怎么办?
Free list中取 > LRU中淘汰 > LRU Flush

页面淘汰
LRU尾部淘汰
Flush LRU淘汰

LRU链表中将第一个脏页刷盘并“释放”
放到LRU尾部?直接放FreeList?

位置移动
old 到 new
new 到 old
在这里插入图片描述
思考:移动时机是什么?
innodb_old_blocks_time
old区存活时间,大于此值,有机会进入new区

在这里插入图片描述

LRU_new的操作
链表操作效率很高,有访问移动到表头?
Lock!!!
MySQL设计思路: 减少移动次数

两个重要参考:
1、freed_page_clock:Buffer Pool淘汰页数
2、LRU_new长度1/4

当前freed_page_clock - 上次移动到Header时freed_page_clock>LRU_new长度1/4

三、MySQL事务实现原理

MySQL事务基本概念

1、事务特性
A(Atomicity原子性):全部成功或全部失败
I(Isolation隔离性):并行事务之间互不干扰
D(Durability持久性):事务提交后,永久生效
C(Consistency一致性):通过AID保证

2、并发问题
脏读(Drity Read):读取到未提交的数据
不可重复读(Non-repeatable read):两次读取结果不同
幻读(Phantom Read):select 操作得到的结果所表征的数据状态无法支撑后续的业务操作

3、隔离级别
Read Uncommitted(未提交读):最低隔离级别,会读取到其他事务未提交的数据。脏读;
Read Committed(提交读):事务过程中可以读取到其他事务已提交的数据。不可重复读;
Repeatable Read(可重复读):每次读取相同结果集,不管其他事务是否提交,幻读;
(两次当前读不会产生幻读)
Serializable(串行化):事务排队,隔离级别最高,性能最差;

MySQL事务实现原理(事务管理机制)

1、MVCC 多版本并发控制
解决读-写冲突
如何工作:隐藏列

–当前读(读在存储引擎中存储的那个数据)
在这里插入图片描述
RR级别下
在这里插入图片描述

2、undo log

回滚日志
保证事务原子性
实现数据多版本
delete undo log:用于回滚,提交即清理;
update undo log:用于回滚,同时实现快照读,不能随便删除
在这里插入图片描述
思考:undolog如何清理?
依据系统活跃的最小活跃事务ID Read view
为什么InnoDB count(*)这么慢?
因为

3、redo log

l实现事务持久性

在这里插入图片描述
写入流程
l 记录页的修改,状态为prepare
l 事务提交,讲事务记录为commit状态
在这里插入图片描述

在这里插入图片描述
意义
体积小,记录页的修改,比写入页代价低
末尾追加,随机写变顺序写,发生改变的页不固定

四、MySQL锁实现原理

在这里插入图片描述
所有当前读加排他锁,都有哪些是当前读?
SELECT FOR UPDATE
UPDATE
DELETE
在这里插入图片描述
在这里插入图片描述

唯一索引/非唯一索引 * RC/RR
4种情况逐一分析

在这里插入图片描述
会出现幻读问题,不可重复读了

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

死锁在库表中有记录,通过kill 那个锁删除

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值