mysql基础知识

一、两阶段提交

首先来解释下什么是顺序io,什么是随机io。

  • 顺序io,直接在文件末尾以append的形式追加内容。
  • 随机io,先找到文件合适的位置,再把内容插入到这个位置上。

可以很明显的看出,随机io要先找到合适的位置,如果文件内容很多,这个过程是很耗时间的。而顺序io直接在文件末尾追加。效率远远高于随机io。

两阶段提交:

假如我们要执行一条sql,要从磁盘里面查询数据,我每次要找它肯定很浪费时间。所以要用一种更高效的方式。搞一个预写日志。这个日志也是在磁盘,日志的写入是顺序io,效率较高。sql的执行是随机io,效率较低,而且可能执行失败。

假如这时候我们往数据库插入一条数据,在sql执行过程中突然断电导致数据没有插入成功。那我们怎么保证数据的持久性呢?上面也说了,insert 是随机io,效率不高,那这时候我们先把这条语句写入到预写日志里面。如果sql执行时断电导致sql执行失败,那就从预写日志里面去读取没有执行的sql来恢复日志。这里的预执行日志就是我们mysql的redolog。但是我们的mysql不止有redolog,还有我们的binlog,这个sql也会写入到binlog里面。我们的binlog也是顺序io。所以我们的两阶段提交是由我们的binlog和redolog来共同保证数据持久性的。既然两份日志都要写,那就必须保证这两份日志是同步且一致的。但是在写的时候这两份日志是分开写的,很难保证两份日志的一致性,在恢复数据的时候尽量保证同时参考两个日志文件,如果一致才提交,不一致直接丢弃。丢弃的是什么?丢弃的是刚刚的sql操作。

 sql更新的流程:

 两阶段提交最主要体现在最后的三步。先写redolog日志,再写binlog日志,写完之后就提交事务,把redolog的事务状态改为commit。数据在刚开始写的时候已经写入到磁盘,只不过事务的状态是prepare阶段,最后提交事务的时候把状态改为commit状态。

二、一条数据是怎么保存到数据库的?

从mysql架构层面来说:

如图所示:

 

首先分为三个阶段:客户端、服务端、执行引擎。客户端只是用来发送sql请求,server端含有几个组件,连接器、分析器、优化器、执行器,一条sql经过这些组件操作,最后再交给我们的执行引擎处理。完整地步骤如下:

  1. 客户端发送sql请求,请求这时来到我们服务端的连接器,先建立连接,验证权限等相关的一些事情。
  2. 当连接成功之后,来到我们的分析器,在分析器里做两件事情:词法分析和语法分析。这里会把sql解析成抽象语法树(AST)。抽象语法树可以去了解下,可以debug下sqlparse框架。
  3.  经过分析器分析成抽象语法树之后,来到了我们的优化器,这里有两个优化:基于cast(成本)优化和基于rule(规则)优化,一般使用基于成本优化较多。经过优化之后,一条sql会生成最终的,性能最高的执行方式。
  4. 然后把这个最优的执行方式交给执行器来执行。通过执行方式发送sql语句去执行引擎执行获取最终的执行结果。

从内存方面来说:

如图所示:

  1. 一条sql语句被加载到内存中,需要执行这条sql,一般我们sql的操作有:select、insert、delete、update。在这里我们做个区分,select为一部分,insert、delete、update为另一部分。因为select只需要把数据放到内存就完事儿了,而 insert、delete、update不仅仅要把数据放到内存中,insert要对数据进行约束检查,delete、update要对数据进行操作。
  2. 当数据被放到内存中后,就在内存中进行增删改操作。注意:增删改完了之后,不是直接写到磁盘里面的。在增删改的时候,一定会触发几个日志:undo log,redo log,binlog。undo log是为了方便回滚产生的(MVCC)。redo log和binlog 是为了保证数据一致性来使用的(两阶段提交)。
  3. 日志写好了,再把数据溢写到磁盘中。把数据溢写到磁盘中,也有几个步骤:先把数据写到系统内存中,通过fsync的指令写到磁盘。
  4. 数据写到磁盘的操作无非两种结果:成功或失败。
    1. 如果成功,直接写个数据就可以了
    2. 如果失败,失败的原因有很多,sql执行失败、磁盘坏了,断电等等。
      1. sql执行失败,需要通过undolog回滚。
      2. 磁盘问题或断电导致写入的失败,需要通过两阶段提交来保证数据的一致性。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值