MySQL是如何实现ACID中的D(持久性)的?

假设你执行了一条 sql 语句:

update user set age = 18 where user_id = 345981

MySQL会直接去磁盘修改数据吗?
明显不会,磁盘IO太慢了,如果每个请求过来 MySQL 都要写磁盘,磁盘肯定扛不住。

那就写内存?
把数据从磁盘load到内存,然后修改内存里的数据。也不行,万一掉电了,内存就没了,数据就再也找不回来。

这其实是很多中间件都会遇到的问题,一个中间件做的再怎么分布式,怎么高可靠,都会遇到这个问题:
数据来了,写磁盘,还是写内存?写磁盘,嫌太慢?写内存,又不安全?

MySQL 的解决方案是:既写内存又写磁盘。数据先写内存,再往磁盘写 redo log,最后在空闲的时候,再把数据刷到磁盘。

那么什么 是redo log
redo log 是磁盘上面的一种log文件,记录了sql语句,是数据的物理变化。这也是它和binlog一个最大的区别,binlog记录的是数据的逻辑变化,这也是为什么 redo log 可以用来 crash recovery,而 binlog 不能的原因之一。
此时有两个问题:。
1:redo log 还是要写磁盘,那不还是很慢?并不是,把 redo log 写到磁盘,比一般的写磁盘要快,原因有:

  • 一般我们写磁盘,都是「随机写」,而 redo log,是「顺序写」
  • MySQL 在写 redo log 上做了优化,比如「组提交」

2:万一我写内存成功,但是把redo log写到磁盘失败了呢?
这里首先要提到「两阶段提交」。哪两阶段呢?还得先说binlog。
还是这一条 update 语句:

update user set age = 18 where user_id = 345981

在这条 update 语句执行的时候,除了生成 redo log,还会生成 binlog。binlog 和 redo log 有很多不同,有一点是一定要知道的,就是 redo log 只是 innodb 存储引擎的功能,而 binlog 是 MySQL server 层的功能,也就是说,redo log 只在使用了 innodb 作为存储引擎的 MySQL 上才有,而 binlog,只要你是 MySQL,就会有。
binlog 一个作用:主从复制,主库把 binlog 发给从库,从库把 binlog 保存了下来,然后去执行它,这样就实现了主从同步。

我们回到两阶段提交,那么当我执行一条 update 语句时,redo log 和 binlog 是在什么时候被写入的呢?这就有了我们常说的「两阶段提交」:

  • 写入:redo log(prepare)
  • 写入:binlog
  • 写入:redo log(commit)

为什么redo log要分两个阶段:prepare 和 commit ?redo log 就不能一次写入吗?

我们分两种情况讨论:

  • 先写 redo log,再写 binlog
  • 先写 binlog,再写 redo log

1、先写 redo log,再写 binlog

这样会出现 redo log 写入到磁盘了,但是 binlog 还没写入磁盘,于是当发生 crash recovery 时,恢复后,主库会应用 redo log,恢复数据,但是由于没有 binlog,从库就不会同步这些数据,主库比从库“新”,造成主从不一致。

2、先写 binlog,再写 redo log

跟上一种情况类似,很容易知道,这样会反过来,造成从库比主库“新”,也会造成主从不一致。

而两阶段提交,就解决这个问题,crash recovery 时:

如果 redo log 已经 commit,那毫不犹豫的,把事务提交

如果 redo log 处于 prepare,则去判断事务对应的 binlog 是不是完整的

是,则把事务提交

否,则事务回滚

两阶段提交,其实是为了保证 redo log 和 binlog 的逻辑一致性。

总结:
innodb在实现高性能写数据的同时,利用redo log,实现了事务的持久性。

转发链接:https://mp.weixin.qq.com/s/IPGQzIhGoWO-2_zAlfEnbQ

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值