Mysql 执行流程,binlog,undo log ,redo log

1、执行流程

Mysql 执行流程,binlog,undo log ,redo log_第1张图片

 mysql主要分为Server层和存储引擎层

  1. Server层:主要包括连接器,查询缓存,分析器,优化器,执行器,所有垮存储引擎的功能都在这一层实现,比如存储工程,触发器,视图,函数等,还有一个通用的binlog日志模块
  2. 存储引擎:主要负责数据的存储和读取,
  3. 连接器:负责用户登录数据,进行用户的身份认证,包括校验账号密码,权限等;只要密码验证通过,连接器会到权限表中查询该用户的所有的权限,只要这个连接不断开,及时管理员在这期间对这用户进行了权限更改,但这个连接维护的还是更改之前的权限
  4. 查询缓存:连接建立后,执行查询语句的时候,会先查询缓存,mysql会校验这个sql是否执行过,以key-value的形式缓存在内存中,如果命中直接返回,如果没有命中,执行后续的操作,完成之后会把对应的结果缓存起来
  5. 分析器:mysql 没有命中缓存,那么就会进入分析器,分析器主要是用来分析SQL语句是来干嘛的,分析器也会分为几步:

    第一步,词法分析,一条SQL语句有多个字符串组成,首先要提取关键字,比如select,提出查询的表,提出字段名,提出查询条件等等。做完这些操作后,就会进入第二步。

    第二步,语法分析,主要就是判断你输入的sql是否正确,是否符合mysql的语法。

    完成这2步之后,mysql就准备开始执行了,但是如何执行,怎么执行是最好的结果呢?这个时候就需要优化器上场了。

  6. 优化器:优化器的作用就是它认为的最优的执行方案去执行(虽然有时候也不是最优),比如多个索引的时候该如何选择索引,多表查询的时候如何选择关联顺序等。
  7. 执行器:当选择了执行方案后,mysql就准备开始执行了,首先执行前会校验该用户有没有权限,如果没有权限,就会返回错误信息,如果有权限,就会去调用引擎的接口,返回接口执行的结果。

1.1 示例分析

select * from manager where age=19  and name='zhangsan'

  • 先检查该语句是否有权限,如果没有权限,直接返回对应的错误信息
  • 查询缓存,如果key命中,直接返回对应信息,否则进入下一步
  • 通过分析器进行词法分析,提取sql的关键元素,比如,select table等,判断sql语句是否有错误,如果没有进行下一步
  • 优化器对sql进行优化(若上述sql我们对name ,age建立了联合索引),此时优化器会将上述sql优化成select * from manager where name='zhangsan' and  age=19  ,这样会执行联合索引,然后回表主键索引查询到符合条件的数据;但注意一点并不是优化器认为的就是最好的结果
  • 优化完毕之后,进行执行,权限校验,如果没有权限就会返回错误信息,如果有权限就会调用数据库引擎接口,返回引擎的执行结果
update manager A set A.age='19' where A.name='李四';

update相对select来说,大体的流程其实没有啥太大的区别,在这过程中引用了日志模块

  • 先查询到李四这一条数据,如果有缓存,也是会用到缓存。
  • 然后拿到查询的语句,把 age 改为19,然后调用引擎API接口,写入这一行数据,InnoDB引擎把数据保存在内存中,同时记录redo log,此时redo log进入prepare状态,然后告诉执行器,执行完成了,随时可以提交。
  • 执行器收到通知后记录binlog,然后调用引擎接口,提交redo log 为提交状态。
  • 更新完成。

疑惑:为什么redo log 要引入prepare预提交状态? 

第一种情况:先写redo log直接提交,然后写binlog;

如果在写完redo log之后,机器挂了,binlog日志没有被写入,机器重启之后,会通过redo log恢复数据,但是这个时候binlog是没有记录这条有问题的数据,后续进行机器备份的时候,会丢失这条数据,主从同步也会有这种现象

第二种情况:先写binlog 然后写redo log

假设写完binlog,机器异常重启,由于没有redo log这条记录,本机是无法恢复这条数据,但是binlog又有记录,备份或者主从同步会新增了这条数据,这样就导致了数据不一致的现象

而redolog 和binlog俩阶段提交,则能很好的避免上述的问题,

,写完binglog后,然后再提交redo log就会防止出现上述的问题,从而保证了数据的一致性。那么问题来了,有没有一个极端的情况呢?假设redo log 处于预提交状态,binglog也已经写完了,这个时候发生了异常重启会怎么样呢? 这个就要依赖于mysql的处理机制了,mysql的处理过程如下:

  • 判断redo log 是否完整,如果判断是完整的,就立即提交。
  • 如果redo log 只是预提交但不是commit状态,这个时候就会去判断binlog是否完整,如果完整就提交 redo log, 不完整就回滚事务。

这样就解决了数据一致性的问题。

1.2 redo log

重做日志

作用:确保事务的持久性,防止在发生故障的时间点,尚有脏页未写入磁盘,在重启mysql服务的时候,基于redo log进行重做,从而达到事务的持久性

1.3 bin log

归档日志

作用:用于复制,在主从复制中,从库利用主库上的bin log进行数据同步

1.3 undo log

回滚日志

作用:保存事务发生之前的数据版本,可以用于回滚,同时可以提供多版本并发控制

你可能感兴趣的:(数据库,mysql,数据库,database)