MySql之更新数据(二)

197 阅读2分钟

前边我们学习了mysql的读操作的整个过程,下边我们来简述一下更新数据时的整个过程。

首先是建立连接,然后去查询缓存中将涉及到的表的数据清空,然后进入分析器做词法分析和语法分析,然后是优化器决定使用哪个索引,然后是执行器,通过调用存储引擎的接口实现数据的更新。

Mysql的数据更新过程中涉及到两个日志文件:redo log和binlog。下边我们来介绍一下这两个日志文件的作用和区别。

Redo log

存储引擎在更新数据时如果每次都直接更新硬盘,由于随机IO的产生,会使得引擎的效率非常低。为了解决这个问题,innodb引擎采用了WAL技术,即write-ahead-log.即每次更新数据,innodb并不会直接更新磁盘里的数据文件,而是先记录redo log并更新缓存,然后就返回结果。之后会按照一定的策略异步更新数据文件。由于redolog是顺序写的,效率很高。从而使得innodb引擎整个的效率很高。

由于redolog的存在,innodb引擎具备了crash-safe的能力。即引擎即使挂掉,也能够安全恢复,不会导致数据丢失。

但是redo log并不是一直存在的,它是滚动写的,数据一旦进入真正的数据文件,对应的redo log也会清楚。

binlog

之前我们了解到mysql分为server层和引擎层。redolog是innodb引擎具备的能力,其他引擎是不具备的,binlog是server层提供的能力。

过程是,当存储引擎返回结果后(对于innodb是写完redolog并更新缓存后),server层会将操作记录到binlog中。binlog会不断追加。

区别

  • redolog是innodb的,binlog是server层提供的
  • redolog是物理日志,而binlog是逻辑日志。即redolog记录了将来数据文件要改成什么样子,而binlog则记录了具体的操作。

两阶段提交

redolog其实采用了两阶段提交的协议,目的是为了保证redolog与binlog的数据保持一致。

过程是,当innodb更新完redolog和缓存后,其实只是prepare阶段,之后返回结果,表示可以提交事物了,server层收到引擎层成功的响应后,写入binlog,然后再次调用引擎层的commit的接口,使得事务提交。最终保证两个log的一致性。

如果没有两阶段提交,有可能会导致redolog成功,而binlog没成功,这样两者就不一致了。