一、数据结构
1. 二叉树
左边叶子节点小于根节点,右边叶子节点大于根节点。
2.红黑树
自适应平衡树,根据节点数量和节点数据自动调整数大小。(数量大了,数高度又高;每个节点只存储一个数据,节点间不连续)
3.B-Tree
B数高度远低于红黑树,叶子节点没指针,叶子节点不连续
4.B+Tree
分为叶子点和叶子节点两类,叶子节点从左到右递增,双项链表指针
非叶子节点不存数据,只存储索引
叶子阶段包含索引字段,双项指针
5.Hash
一次计算就能找到数据存储位置,但是只能满足 = ,范围查找不支持,还存在hash冲突问题
二、存储引擎
MyISAM (非聚集)
数据和索引文件是分开存储的
InnoDB 聚集
表数据按照B+Tree生成,叶子节点存储数据
三、MySQL内部组件结构
连接器: 与客户端进行连接通信
查询缓存:执行select 语句会先到缓存中进行查找,查找不到在执行另外分支的流程。(MySQL 8.0 已去掉查询缓存)
词法分析器:对select * from T 的表名进行分析,分析语法是否符合规则
优化器:优化器是根据语句判断使用哪个索引,以及内部优化机制
执行器:先判断是否有这个表的执行权限,有权限根据执行引擎调用接口查询。
词法分析器:
四、InnoDB底层原理和日志机制
例:执行 update T set name='李四' where id=1;
step1:首先会从磁盘文件中找到id=1记录所在的page,将这一页的数据都加载到buffer pool缓存池中;
step2:将原有数据快照记录到undoLog日志里面,回滚使用;
step3:更新内存操作,将buffer pool里面的数据进行更新
step4: 写redo log日志到redo log buffer
step5:redo log顺序写入磁盘,redo log修理修改,记录哪一个page做了什么修改
step6:准备提交事务,写binlog写入磁盘
step7:binlog写commit到redo log里面,双写保持数据一致
step8:buffer pool每1s 新线程写提交数据到磁盘文件
1.Buffer pool
缓冲池默认大小128M,可以进行调整;缓存磁盘文件中的数据;
数据页16KB,MySQL抽象出来的数据单位
2.Redo Log
Redo Log利用WAL(Write-Ahead Logging)机制来保证故障恢复的安全性(crash-safe);WAL的核心思想是先写日志,再写磁盘。
redo log可以保证事务提交后:如果事务中由增删改SQL更新的缓存页还没刷新到磁盘时MySQL宕机,那么MySQL重启后,就可以把redo log重做一遍,恢复事务在当时更新的缓存页,然后再把缓存页刷新到磁盘。所以redo log的本质是保证事务提交后,修改的数据绝对不会丢失。
redo log日志的格式大致为:对表空间XX中的数据页XX中的偏移量为XXXX的地方更新了数据XXX。重启后可以根据redo log,在Buffer Pool里恢复宕机前的事务更新。
Redo Log Buffer解析
MySQL执行完增删改的SQL语句后:会先让redo日志进入Redo Log Block,然后再写入磁盘的redo日志文件。
Redo Log Buffer是MySQL启动时向操作系统申请的一块连续内存空间。Buffer Pool也是MySQL启动时向操作系统申请的一块连续内存空间。Buffer Pool会在申请内存后划分很多空的缓存页和一些链表结构。Redo Log Buffer也会在申请内存后,划分很多空的Redo Log Block。Redo Log Buffer的大小,默认是16MB,最大值4096MB。
3.Undo Log
Undo Log记录了事务在修改数据之前的原始状态,用于在事务回滚时撤销未完成的修改,确保事务的原子性和隔离性
Undo Log主要的功能有两个:事务回滚和MVCC
-
实现事务回滚,保障事务原子性
-
与 Read-View 一起构成了 MVCC 的基础
首先来说事务回滚,事务如何通过Undo Log进行回滚操作呢?其实很简单,只需要在Undo Log日志中记录事务中的反向操作即可,发生回滚时直接通过Undo Log中记录的反向操作进行恢复。例如:
-
事务进行insert操作,Undo Log记录delete操作。
-
事务进行delete操作,Undo Log记录insert操作。
-
事务进行update操作(value1 改为value2 ),Undo Log记录update操作(value2 改为value1 )。
每一条的undo log都记录了事务Id和回滚指针;
为了 提升 Undo Log 读写性能, Undo页还存在于Buffer Pool中,因为Buffer Pool 是 InnoDB 的内存缓存,用于存储数据页和索引页,以便快速访问。它通过减少磁盘 I/O,提高数据库的整体性能。将Undo页放在缓存中,可以加速事务的回滚和数据恢复。
当事务commit之后,不会立即删除,会保留至所有快照读完成。
4.Bin Log
binlog 是逻辑日志,记录内容是语句的原始逻辑,类似于 “给 ID=2 这一行的 c 字段加 1”。binlog 会记录所有涉及更新数据的逻辑操作,并且是顺序写,属于 MySQL Server 层。
bin Log作用
-
备份恢复,实现崩溃一致性(Crash Consistency)。原理是每次事务进行提交时,都会将增、删、改操作以追加的方式记录到Binlog文件中。
-
主从复制,实现 主从复制的一致性。原理是主从复制常用于MySQL主从集群搭建,MySQL从节点通过监听主节点Binlog日志进行同步即可。