Mysql原理-执行流程-binLog、redoLog、undoLog的作用-事务的四大特性

作为一名程序员,相信百分之九十九点九的人都对mysql不会陌生,从大学或者培训班出身的都有接触过mysql,其实经过这么长时间的接触,对mysql还是一知半解,在工作中写sql也好,优化也罢,都没有对mysql一个透彻的理解。仅仅只是一个会用的程度,所以我决定要好好的重新认识一下mysql。

Mysql查询语句执行流程

当我们在一些Navicat或者其他的数据库管理工具中执行一条查询语句,数据库就会返回相应的数据给我们,那么从执行到数据的返回,数据库都经过了哪些步骤呢?
在这里插入图片描述
如上图。
从你点击执行sql的那一刻开始,Navicat需要对数据库进行一次连接请求。请求成功后就会对query_cache缓存进行一次查询,看你当前sql的结果是否在缓存里面,如果有则直接返回数据,没有缓存则会到Paser解析器里进行词法解析语法解析。解析完成后会来到预处理进行权限验证语义解析,之后会把sql交给优化器进行优化。优化器优化完成之后会交给执行计划,最后执行器负责按照执行计划拆解好的步骤去存储引擎里执行,最后将结果返回客户端。

名词解释:

  • 词法解析: 简单来说就是将sql语句拆解为多个元素,例如:select name from
    userTable;词法解析会将sql拆解为select,name,from,和userTable。其中select和from为关键字,name和userTable为非关键字。

  • 语法解析: 会判断这段sql是否符合sql语法,比如from打成了form,那么语法解析到错误之后就会抛出异常。并且语法解析还会将sql生成解析树,解析树类似下图。
    在这里插入图片描述

  • 语义解析: 会根据语法解析后的解析树进行检查,看解析树是否有问题,比如是否有关键字错误,关键字的顺序是否有问题等。

  • 优化器: 我们平常写的一些sql,优化器会对其进行一次优化,使其尽可能的使用到索引,提高查询效率。例如我们建立了一个联合索引:索引字段为name,phone
    而我们sql的却是select name from userTable where phone = ‘1562498497x’ and
    name = ‘silence’。那这个时候优化器就会对sql进行调整变为:select name from userTable
    where name = ‘silence’ and phone = ‘1562498497x’
    。这样sql在执行的时候就会用到这个联合索引。

  • 执行计划: 执行计划是一个重点,关于执行计划的解释大家可以看这个博主的博客,写的非常好,每个字段都有示例。https://www.cnblogs.com/yinjw/p/11864477.html

索引注意事项

创建索引是提高sql执行效率的一个重要手段,那么我们在创建索引的时候也需要注意以下事项:

  • 索引的个数不是越多越好,并不是把表里所有字段都加上索引,执行效率就会提高。
  • 散列度低(distinct 的行数/总行数)的字段,不要创建索引。
  • 随机无序或频繁更新的字段,不要创建索引。
  • 创建复合索引时要避免有冗余索引。

以下几种情况会导致索引失效:

  • 使用了函数,表达式,运算符
  • 出现了类型的隐式转换
  • like条件字符前有%
  • 使用了<>,!=,not in

binLog、redoLog、undoLog的作用

binLog

binLog主要用于主从复制,Mysql集群时数据的同步需要依靠binLog来实现。binLog记录的是对数据更改的命令,不会记录select,show这类命令因为没有对数据有更改。

redoLog

redoLog主要用于崩溃恢复,主要记录的是事务操作的变化,记录的是数据修改之后的值。不管事务是否被提交都会进行记录。如果事务被回滚,则记录的数据也会被回滚。
如果遇到突然断电,或者系统突然宕机,那么InnoDB引擎就会通过redoLog来恢复数据到断电/宕机前的时刻,来保证数据的完整性。

undoLog

undoLog保证了事务的原子性。在undoLog中存放的是数据的历史版本。在InnoDB中,insert操作在事务提交之前只对当前事务可见,对其他事务是不可见的,在事务提交之后记录在undoLog的inert数据会被删除,因为新插入的数据没有历史版本。而对于update,delete操作则会保留多个版本。

例如:事务S1和S2想要同时访问数据A,S1想要将数据A修改为B,而S2想要查询数据A,那么在没有MVCC(多并发版本控制)之前只能依赖加锁,谁先拥有锁谁先执行,另一个等待。但是在高并发下这种加锁会导致效率低下。所以InnoDB引擎通过MVCC的方式来读取当前执行时间数据库中行的数据。如果读取的行正在执行update,delete操作,这时读取操作不会等到更改操作执行完毕之后再去查询,而是读取一个快照数据(undoLog)。在InnoDB中,要对一条数据进行处理,会先看这条数据的版本号是否大于当前事务的版本号,如果大于,则需要从历史快照中读取,来保证数据的一致性。而历史数据存在在undoLog中,对数据修改所加的锁并不会影响undoLog,所以不会耽误用户对历史数据饿读操作,从而达到非一致性锁定读,提高并发性能。

MVCC

MVCC(Multi version concurrence controller)多版本并发控制,是一种并发控制的方法。

事务的四大特性

  • 原子性: 要么都成功,要么都失败。通过事务日志undoLog来实现数据的回滚操作,以保证事务的原子性。
  • 持久性: 事务一旦被提交,就保存到磁盘里了,不会凭空消失。依赖于redoLog+双写缓存(double write buffer)来实现。
  • 隔离性: 当一个事务执行完之前,其他事务有数据的增删改操作,对事务A是不可见的。
  • 一致性: 事务发生前和发生后要保证数据的完整性一致。

事务并发会带来哪些问题?四种事务隔离级别是什么?

事务并发会发生脏读,不可重复读,幻读的问题。

  • 脏读: 当一个事务A还未提交时,事务B对该行数据有更新操作并且也未提交,这时候事务A再次进行查询就查到了事务B修改后的值,这种情况叫做脏读。
  • 不可重复读: 当事务A还未提交时,事务B对该行数据进行了修改或者删除操作并提交了事务,这时候事务A再次进行查询就查到了事务B修改后的值,这种情况叫做不可重复读。
  • 幻读: 当事务A还未提交时,事务B进行了插入操作并提交了事务,这时候事务A再次查询,且查到了事务B插入的数据,这种情况叫做幻读。

四种事务隔离级别分别是:未提交读(Read UnCommitted)、已提交读(Read Committed)、可重复读(Repeatable Read)以及串行化(Serialiable)
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Silence-wen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值