MySQL 数据库中的两阶段提交,不知道您知道不?这篇文章就简单的聊一聊 MySQL 数据库中的两阶段提交,两阶段提交发生在数据变动期间(更新、删除、新增等),两阶段提交过程当中涉及到了 MySQL 数据库中的两个日志系统:redo 日志和 binlog 文件。mysql
redo 日志前面已经介绍过了,就再也不介绍了,简单的聊一聊 binlog 文件,binlog 是 MySQL server 层提供的二进制文件,所以全部的存储引擎均可以使用 binlog 功能,binlog 是追加写的逻辑日志,记录了执行语句的原始逻辑,文件写到指定大小后会切换到下一个文件继续写,并不会覆盖之前写过的日志文件。sql
binlog 日志文件主要用于数据恢复和集群环境下各服务器之间的数据同步,在工做中,咱们误删了数据或者表之类,若是须要恢复的话都是利用 binlog 日志来恢复的,因此 binlog 日志是 MySQL 数据库中比较重要的模块。数据库
知道这两个日志以后,咱们把重点回到 MySQL 数据库两阶段提交,前面咱们说了两阶段提交发生在数据变动期间,为了更好的理解两阶段提交,咱们用一条更新命令来加以说明,更新语句以下:服务器
mysql> update T set c=c+1 where id=2;
复制代码
假设未更新前 id=2 的这行数据 c 的值为 0 ,这条更新语句在 MySQL 数据库内部是如何执行的呢?在下面这张执行流程图:微信
从流程图中能够看出,在 InnoDB 存储引擎下,一条 update 语句在 MySQL 内部执行大概会经历下面五个步骤:学习
一、执行器先找引擎取 id=2 这一行数据,若是 ID=2 这一行所在的数据页原本就在内存中,就直接返回给执行器;不然,须要先从磁盘读入内存,而后再返回。spa
二、执行器拿到引擎给的行数据,把这个值加上 1,好比原来是 N,如今就是 N+1,获得新的一行数据,再调用引擎接口写入这行新数据。日志
三、引擎将这行新数据更新到内存中,同时将这个更新操做记录到 redo log 里面,此时 redo log 处于 prepare 状态。而后告知执行器执行完成了,随时能够提交事务。code
四、执行器生成这个操做的 binlog,并把 binlog 写入磁盘。cdn
五、执行器调用引擎的提交事务接口,引擎把刚刚写入的 redo log 改为提交(commit)状态,更新完成。
在这五步中,注意用红颜色标出来的部分,redo 日志被分割成 prepare 和 commit 两个阶段提交,这个过程称为两阶段提交,不将 redo 日志拆分红两步提交行不行?
咱们能够用反推法来证实,假设不使用两阶段提交,那么就有两种状况,一种是先提交 redo 日志再提交 binlog 日志,另外一种是先提交 binlog 日志再提交 redo 日志,一块儿来看看这两种提交方式有什么问题?
先写 redo log 后写 binlog。假设在 redo log 写完,binlog 尚未写完的时候,MySQL 进程异常重启。在这个过程当中更新发生了异常,redo 日志是能够在数据库发生异常是保证数据的持久性,启动后通过 redo 日志数据恢复后 c 的值是 1,可是 binlog 并无写完,因此在 binlog 日志文件中并无记录这条更新语句,若是用这个 binlog 日志文件来恢复临时库的话,恢复出来 id =2 的这行数据的 c 的值为 0,与原库的值就不一致了。
先写 binlog 后写 redo log。若是在 binlog 写完, redo 日志还没写,系统崩溃,系统重启后,id=2 的这行数据的 c 的值仍是为 0,可是在 binlog 日志文件中却记录了此次更新,若是须要用 binlog 日志文件来恢复临时库的话,那么 id=2 的这行数据 c 的值就为 1,这样与原库的值就不一致了。
从这两个假设中,咱们能够看出不管先提交那个日志文件都有可能出现数据不一致的现象,日志文件两阶段提交技术就解决了redo 日志和 binlog 日志文件记录数据不一致的问题,从而保证了在数据恢复时数据的一致性。
以上就是 MySQL 数据编辑中涉及到的两阶段提交,但愿这篇文章对您的学习或者工做有所帮助,若是您以为文章有帮助,欢迎帮忙转发,谢谢。
目前互联网上不少大佬都有 MySQL 相关文章,若有雷同,请多多包涵了。原创不易,码字不易,还但愿你们多多支持。若文中有所错误之处,还望提出,谢谢。
欢迎扫码关注微信公众号:「互联网平头哥」,和平头哥一块儿学习,一块儿进步。