深入理解Mysql架构原理

什么是Mysql驱动

先通过maven引入一段配置
在这里插入图片描述
mysql驱动用来和数据库建立连接。

各种语言编写的代码,通过Mysql驱动去访问数据库。

什么是数据库连接池

处理多线程并发请求数据库建立连接,以及线程不断销毁和创建的效率问题。
常见的连接池:DBCP,C3P0, Druid
在这里插入图片描述
Mysql的连接池维护了与系统之间的多个数据库连接。系统跟Mysql建立连接的时候会传递过来账号,密码,库表权限。

Mysql架构设计

查询解析器

把传过来的sql解析成Mysql能看懂得语句

查询优化器

对sql语句进行优化,选择最优路径

执行器

用来调用存储引擎

存储引擎

用来操作磁盘

整体流程

首先会有一个线程去获取数据库连接池中的请求sql,通过Mysql内部sql接口进行接收,传给SQL解析器对sql解析成Mysql能够读懂的语言,解析之后,把sql交给查询优化器,对sql进行优化,选择出最优路径,就是执行计划,通过执行器按照执行计划,去调用存储引擎对磁盘数据进行操作。
在这里插入图片描述

存储引擎InnoDB

InnoDB中重要结构–bufferPool

sql语句在执行增删改查的时候会先将磁盘中的数据读取到内存中,内存中用来存储磁盘缓存数据的区域就存储在bufferpool缓冲池中。用来加快sql的执行速度。

innoDB提供的undolog和redolog

由于数据的增删改查都在内存的bufferpool中,如果某条数据在内存中进行了修改,但是此时磁盘中还没有进行存储,此时如果宕机或者断电,就无法将内存中的数据同步到磁盘中。
undolog:用来记录数据修改之前的记录,用来做回滚操作。
redolog:用来记录数据修改之后的值,用来断电恢复数据。事务提交之后,会将数据优先写入redolog。
binlog:mysql提供的日志、

bufferpool中的链表都有什么作用

mysql从磁盘读取数据都是读取一个内存页,在bufferpool中也是以一个一个的内存页进行存储的。每个缓存页会绑定一个描述数据,通过描述数据之间进行链表链接。
free链表:用来记录bufferPool中有哪些缓存页还空着,可以用来存放数据
flush链表:用来记录bufferPool中的数据页是脏数据,(就是数据进行了更新操作,但是还没有刷回磁盘)。每次进行刷盘的时候,就会把数据页从flush链表中删除,增加到free链表中。
lru链表:通过lru规则,把经常读取的数据放在链表的最前面不被清理掉,不经常使用的数据就会被移动到链表的尾部,从尾部开始进行刷盘。

因为mysql有预读机制,当去查询一条数据的时候,会把相邻的数据一起读进缓存,这样将就会导致之前使用频繁的数据被挤到链表的最后,导致提前被刷盘。所以lru链表采用了冷热链表的方法来解决这个问题。 lru链表被分成两个部分,前半部分为热数据区域,后半部分为冷数据。当数据刚开始被读进内存的时候,他会被放在lru链表的冷数据头部。当过了一秒钟之后再次被调用的数据,就会被移动到热数据区域的头部。为了避免频繁移动链表带来的开销,所以链表的前四分之一部分进行使用的时候不需要移动。
在这里插入图片描述

Mysql多事务并发隔离级别

MVCC机制:multi-version concurrent control 多版本并发控制机制
多个事务并发运行的时候,同时脏写一个数据,会产生脏写,脏读,不可重复读,幻读。、
脏写,两个事务更新一个数据,一个人回滚了,把另一个人的数据回滚没了
脏读: 就是一个事务读到另一个事务没提交时候的修改数据,然后另一个事务回滚了,下次读取不到了
不可重复读: 就是多次读写,别的事务多次修改并提交,导致多次读取的数值不一样。
幻读: 范围查询,每次查到的数据不一样,就是别的事务进行了插入。

针对这些问题有了 RU,RR,RR,和串行四个隔离级别。
RU:只能避免脏写
RC:避免脏写和脏读
RR: 避免脏读,脏写,不可重复读
串行让事务串行执行,避免所有问题

Mysql实现了MVCC机制,基于undolog多版本链条+readView机制。默认RR级别、

我们数据库中的每行数据,除了我们肉眼看见的数据,还有几个隐藏字段,得开天眼才能看到。分别是db_trx_id、db_roll_pointer、db_row_id。
db_trx_id:代表当前事务的id
db_roll_pointer:回滚指针,指向上一个版本的地址。

Read_View:读视图

Read View几个属性

trx_ids: 当前系统活跃(未提交)事务版本号集合。

low_limit_id: 创建当前read view 时“当前系统最大事务版本号+1”。

up_limit_id: 创建当前read view 时“系统正处于活跃事务最小版本号”

creator_trx_id: 创建当前read view的事务版本号;

Read View可见性判断条件
db_trx_id < up_limit_id || db_trx_id == creator_trx_id(显示)

如果数据事务ID小于read view中的最小活跃事务ID,则可以肯定该数据是在当前事务启之前就已经存在了的,所以可以显示。

或者数据的事务ID等于creator_trx_id ,那么说明这个数据就是当前事务自己生成的,自己生成的数据自己当然能看见,所以这种情况下此数据也是可以显示的。

db_trx_id >= low_limit_id(不显示)

如果数据事务ID大于read view 中的当前系统的最大事务ID,则说明该数据是在当前read view 创建之后才产生的,所以数据不显示。如果小于则进入下一个判断

db_trx_id是否在活跃事务(trx_ids)中

不存在:则说明read view产生的时候事务已经commit了,这种情况数据则可以显示。

已存在:则代表我Read View生成时刻,你这个事务还在活跃,还没有Commit,你修改的数据,我当前事务也是看不见的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值