MySQL 的存储引擎 InnoDB的架构(Redolog UndoLog binLog 是如何支持事务的);各种宕机场景解决措施【THIS】【Deal It 23/8/8】

 InnoDB引擎架构:

在这里插入图片描述

InnoDB引擎的内存部分:

包括 用于存放数据的缓冲池BufferPool;

        用于 暂存RedoLog,之后统一刷到磁盘的RedoLogBuffer ; 

        用于 避免数据从 内存 刷回到 磁盘 过程中 出错,而引入的DoubleWriteBuffer


描述一个DML语句的执行流程:

(假设该DML语句是一个UPDATE语句,该语句作为一个事物要求InnoDB执行)

【MySQL执行器会涉及哪些操作?MySQL Server 涉及 binlog 但是好像不操作UndoLog RedoLog 啥的吧】

1.MySQLServer执行器根据DML语句从InnoDB引擎内存BufferPool中找数据,若不在,从磁盘中load该内容对应的页到BufferPool中

 这块涉及的点在于:优化的LRU

2. 引擎根据DML生成UndoLog,并将UndoLog写回到InnoDB磁盘区中存放UndoLog的地方

问题一:UndoLog的具体内容是什么?

UndoLog中记录一条与DML相反的命令:

例如:DML执行:UPDATE table1 set  age = 10 where id=1 ;

           而原来 id=1的age为5

           那么,UndoLog中生成的命令就是:UPDATE table1 set  age = 5 where id=1 ;

           ==》这样,当事务发生错误,可以通过UndoLog来回滚到事务执行前的状态              

问题二:UndoLog 的作用 ?

1. 提供回滚操作【undo log实现事务的原子性】MySQL就要执行回滚(rollback)操作,利用undo log将数据恢复到事务开始之前的状态。

2. 提供多版本控制(MVCC)【undo log实现多版本并发控制(MVCC)】当读取的某一行被其他事务锁定时,它可以从undo log中分析出该行记录以前的数据版本是怎样的,从而让用户能够读取到当前事务操作之前的数据【快照读】。

【有些操作只能获得快照读 -- MVCC的内容(MVCC如何根据UndoLog来实现多版本,UN到哦Log是如何存放回滚指针事务链的),可以链接补充在这里】

 问题三:UndoLog 如何指导回滚操作 ?

1. 当MySQLServer 对值进行修改Or值修改完但是值还存放在InnoDB引擎内存中时,总之就是MySQL寄了,内存中新值或者半新半旧的值还没刷回到磁盘中就没了,

==》回滚,那么就使用UndoLog恢复之前的状态新的值在内存中但是

为什么 Undo Log不也搞一个Undo Log Buffer,也给Undo Log提提速,【不确定是否存在Undo Log Buffer,因此这个问题存疑】

那我们假设有这个一个Buffer存在于InnoDB,将事务开始前的数据状态写入了Undo Log Buffer中,然后开始更新数据。

突然啪一下,很快啊,MySQL由于意外进程退出了,此时会发生一件很尴尬的事情,如果更新的数据一部分已经刷回磁盘了,但是此时事务没有成功需要回滚,你发现Undo Log随着进程退出一起没了,此时就没有办法通过Undo Log去做回滚。

那如果刚刚更新完内存,MySQL就挂了呢?此时Redo Log Buffer甚至都可能没有写入,即使写入了也没有刷到磁盘,Redo Log也丢了。

其实无所谓,因为意外宕机,该事务没有成功,既然事务事务没有成功那就需要回滚,而MySQL重启后会读取磁盘上的Redo Log文件,将其状态给加载到Buffer Pool中。而通过磁盘Redo Log文件恢复的状态和宕机前事务开始前的状态是一样的,所以是没有影响的。然后等待事务commit了之后就会将Redo Log和Binlog刷到磁盘。

3. MySQL Server 执行器 解析 DML语句,对数据进行操作(更新 id=1的条目其age的值),调用引擎接口将新的age值重新写入,引擎则把这个新的数据存放在 BufferPool中 

涉及的问题是:何时将BufferPool中的 数据 刷盘到 磁盘文件中

以及刷盘前 MySQL寄了,

刷盘中 MySQL寄了,

                                                        两种情况下的处理办法

4. 引擎 把数据存放在 BufferPool,同时 引擎将该语句执行后的数据状态 写入到 RedoLogBuffer中。当事务全部执行完毕,附上内部XA事务的ID并将状态置为Prepare。此时可以根据RedoLog指定的策略将RedoLog刷盘到磁盘中了。

(之所以经过一次 RedoLogBuffer的中转是因为一个事务可能不止有一条DML语句,多个DML语句生成的RedoLog内容先暂存到RedoLog Buffer中,当事务结束,再一起(减少IO)刷回到 磁盘的RedoLog空间中)

redo log buffer中的数据也不是直接入盘,中间还会经过操作系统内核空间的缓冲区

在这里插入图片描述

os buffer,然后才到磁盘上的redo log file。innodb_flush_log_at_trx_commit参数可以控制redo log buffer何时写入redo log file,该参数有三个可选值,分别如下:

0:延迟写。不会在事务提交时立即将redo log buffer写入到os buffer,而是每秒写入os buffer,然后立即写入到redo log file,也就是每秒刷盘
1:实时写,实时刷。每次事务提交都会将redo log buffer写入os buffer,然后立即写入redo log file。数据能够及时入盘,但是每次事务提交都会刷盘,效率较低
2:实时写,延时刷。每次事务提交都将redo log buffer写入os buffer,然后每秒将os buffer写入redo log file
 

5. RedoLog写入到磁盘成功后,将BinLog 同样写入到磁盘的对应BinLog空间,同样也记录BinLog对应的XA 事件ID。此时InnoDB引擎新启一个线程将BufferPool中的数据刷到磁盘中( 只要保证日志先行:先写了RedoLog,再把BufferPool数据刷回磁盘)

mysql checkpoint技术:  mysql checkpoint技术 - 简书 (jianshu.com)

6. 当binLog刷回到磁盘中时,MySQL Server执行器调用InnoDB存储引擎的提交API,将RedoLog对应的事务状态标识修改为Commit。

4、5、6三步就是 为了实现 RedoLog和Binlog在事务提交时的数据一致性 而采用的 两提交2PC协议

为什么要保证Redo Log和Binlog在事务提交时的数据一致性呢?

在两阶段提交的不同时刻,MySQL 异常重启会出现什么现象?

1. 当RedoLog内容写入到磁盘中,MySQL异常:

此时:BinLog还在内存中,因此BinLog数据丢失,同时,磁盘中的RedoLog李对于该事务的标记还只是Prepare。

==》崩溃恢复时,由于事务没有提交,那么,调用UndoLog 回滚

2. binlog 写到磁盘,redolog 还没被标记为 commit 前 MySQL异常:

那崩溃恢复的时候 MySQL 会怎么处理?

崩溃恢复的规则:

7. MySQL Server执行器调用InnoDB存储引擎的接口提交事务,整个过程结束。


Ref:

玩转MySQL:InnoDB引擎存储结构+特性ChangeBuffer和DoubleWriter分析 - 知乎 (zhihu.com)

必须了解的MySQL三大日志:binlog、redo log和undo log - 知乎 (zhihu.com)

为什么需要redo log

我们都知道,事务的四大特性里面有一个是持久性,具体来说就是只要事务提交成功,那么对数据库做的修改就被永久保存下来了,不可能因为任何原因再回到原来的状态。那么mysql是如何保证一致性的呢?最简单的做法是在每次事务提交的时候,将该事务涉及修改的数据页全部刷新到磁盘中。但是这么做会有严重的性能问题,主要体现在两个方面:

  • 因为Innodb是以页为单位进行磁盘交互的,而一个事务很可能只修改一个数据页里面的几个字节,这个时候将完整的数据页刷到磁盘的话,太浪费资源了!
  • 一个事务可能涉及修改多个数据页,并且这些数据页在物理上并不连续,使用随机IO写入性能太差!

因此mysql设计了redo log,具体来说就是只记录事务对数据页做了哪些修改,这样就能完美地解决性能问题了(相对而言文件更小并且是顺序IO)。

MySQL--buffer pool、redo log、undo log、binlog_黄智霖-blog的博客-CSDN博客

数据库系列3:InnoDB的结构和更新语句执行的详细过程_innodb 历史zhixing语句_纵横千里,捭阖四方的博客-CSDN博客

数据库系列2:更新语句执行的基本过程_纵横千里,捭阖四方的博客-CSDN博客

MySQL中两个重要的日志(redolog和binlog)_数据库两个日志文件怎么写_wy471x的博客-CSDN博客

 mysql checkpoint技术 - 简书 (jianshu.com)

基于Redo Log和Undo Log的MySQL崩溃恢复流程 - 知乎 (zhihu.com)

简单了解InnoDB底层原理 (qq.com)

mysql redo log为什么有两阶段提交/为什么有prepare和commit两个状态?_redolog prepare_wu@55555的博客-CSDN博客

mysql 物理日志之redo log(重做日志)原理和介绍 - 简书 (jianshu.com)

锁、乐观悲观锁 这块 看看第四节视频里面有没有,没有就看看理解一下记录一下,这块重点常考【是吧】

一个总结的比较全面的MySQL内容;【单机MySQL】

MySQL 三万字精华总结 + 面试100 问,和面试官扯皮绰绰有余(收藏系列) - 知乎 (zhihu.com)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值