一条SQL更新语句是如何执行的

在这里插入图片描述
前面的步骤和查询语句一样。需要注意的是,更新结果也需要写入到查询缓存中。

  1. 执行器先找引擎取ID=2这一行。ID是主键,引擎直接用树搜索找到这一行。如果ID = 2这一行所在的数据页本来就在内存中的缓存池中,就直接返回给执行器;否则,需要从磁盘读入内存,然后再返回。
  2. 执行器拿到引擎给的行数据,把这个值加上1,比如原来是N,现在就是N+1,得到新的一行数据,再调用引擎接口写入这行新数据。
  3. 引擎将这行新数据更新到内存中,同时将这个更新操作记录记录到redo log里面,此时redo log处于prepare状态。然后告知执行器执行完全了,随时可以提交事务。
  4. 执行器生成这个操作的binlog,并把binlog写入磁盘。
  5. 执行器调用引擎的提交事务接口,引擎把刚刚写入一点redo log改成提交(commit)状态,更新完成。
    在这里插入图片描述

什么是redo log重做日志,为什么会存在

redo log又叫重做日志。是InnoDB引擎中为了解决crash safe问题设计的。它是物理日志,记录的是“在某个数据页上做了什么修改,redo log是循环写的,空间固定会用完。
需要注意当redo log满了在擦除旧记录的时候,不能接收新的更新请求,有可能导致MySQL卡顿,对于并发量大的系统,适当设置redo log的文件大小非常重要。
在这里插入图片描述

什么是undo log回滚日志

顾名思义提供了回滚的作用。还有另外一个作用,就是多个行版本控制(MVCC),保证事务的原子性。在数据修改的流程中,会记录一条对当前操作相反的逻辑日志到undo log中,如果某些原因事务导致失败了,可以借助undo log进行回滚,保证事务的完整性。

归档日志binlog

binlog是在MySQL的server层产生,不属于任何引擎,主要记录用户对数据库的SQL语句。
之所以称为归档日志,是因为binlog不会像redo log一样擦掉之前的记录循环写,而是一直记录(超过有效期才会被清理),如果超过单日志的最大值(默认1G,可以通过变量max_binlog_size设置),则会新起一个文件继续记录。但由于日志可能是基于事务来记录的(InnoDB),而事务是绝不可能也不应该跨文件记录的,如果正好binlog日志文件达到了最大值但事务还没有提交则不会切换新的文件记录,而是继续增大日志,所以max_binlog_size指定的值和实际的binlog日志大小则不一定相等。

正是由于binlog有归档的作用,所以binlog主要用作主从同步数据库基于时间段的还原

  • 如果是主从模式下,binlog是必须的,因为从库的数据同步依赖的就是binlog
  • 如果是单机模式下,比格犬不考虑数据库基于某个时间点的还原,binlog就不是必须,因为redo log就可以保证crash-safe能力,但如果万一需要回滚到某个时间点的状态,就无能为力了。所以binlog建议一直开启。

三个日志可以简化吗

综上,在主从模式下三个日志都是必须的,而单击模式下,binlog可以视情况而定,保险起见最好开启。

什么是WAL(write-ahead logging)机制,好处是什么

WAL技术全称write-ahead logging。它的关键点就是先写日志再写磁盘。也叫做日志先行技术。保证了数据一致性和持久性,并且提高语句执行性能。

  1. 因为直接写磁盘文件是随机写,开销大性能低,没办法满足MySQL的性能要求。所以才会设计成先在内存中对数据进行更改,再异步写入磁盘。
  2. 内存不可靠,如果断电重启,内存中的数据会丢失,所以还需要加上写日志的步骤。并且写日志虽然是写磁盘,但是因为是顺序写,所以开销要比随机写小。

redo log为什么可以保证crash safe机制

redo log日志是物理日志,记录了对数据页的操作,可以通过短时重放来恢复数据。

什么是两阶段提交?

两阶段提交就是将redo log的写入拆做两个步骤,prepare和commit,这就是“两阶段提交”。

为什么需要两阶段提交

如果不用两阶段提交的话:

  1. 先写完redo log 再写binlog
    假设redo log写完,binlog还没有写完。此时MySQL进程异常重启。系统奔溃恢复之后,redo log已经写完,所以数据恢复回来,c = 1但是binlog没写完就crash,这时候binlog没有记录,因此如果采用binlog恢复临时库的话,临时库会少了一次更新,恢复出来 c = 1,与原库的值不同。
  2. 先写binlog后写redo log。如果写完binlog之后crash,由于redolog,奔溃恢复之后,该行c = 0。但是binlog已经记录了c = 1,如果以后采用binlog来恢复时候,就会多出一个事务。
    综上,如果不采用两阶段提交,那么数据库的状态可能和它的日志恢复出来的库的状态不一致。

两节点的提交的方式会存在什么问题,解决方法

在两阶段提交的流程基础上,还需要加一个锁来保证提交的原子性,从而保证多事务的情况下,两个日志的提交顺序一致。
虽然通过加锁解决了顺序一致性问题,但是并发量较大的时候,就会导致对锁的争用,性能不佳。除了锁的竞争会影响到性能之外,每个事务都会进行两次fsync(写磁盘),一次redo log 写磁盘,另一次是binlog落盘。对于普通磁盘,每秒QPS大概就是几百。

什么是组提交?用于解决什么问题?

  • 在没有开启binlog时,
    Redo log 的刷盘操作将会是最终影响MySQL TPS的瓶颈所在。为了缓解这一问题,MySQL使用了组提交,将多个刷盘操作合并成一个,如果说10个事务依次排队刷盘的时间成本是10,那么将这10个事务一次性一起刷盘的时间成本近似于1。
  • 开启binlog时
    为了保证redo log和binlog的数据一致性,MySQL使用了二阶段提交,由binlog作为事务的协调者。而引入binlog又成为了性能瓶颈,先前的redo log组提交也成了摆设。为了再次缓解这一问题,MySQL增加了binlog的组提交,目的是同样将binlog的多个刷盘操作合并成一个,结合redo log已经实现的组提交,目的是同样将binlog的多个刷盘操作合并成一个,结合redo log本身已经实现的组提交,分为三个阶段(Flush、sync阶段、Commit阶段)完成binlog组提交,最大化每次刷盘的收益,弱化磁盘瓶颈,提高性能。
    在这里插入图片描述
    https://www.cnblogs.com/xibuhaohao/p/10907903.html
    https://www.pianshen.com/article/12521907901/
    假设事务提交过程中,MySQL进程突然奔溃,重启后是怎么保证数据不丢失的?数据恢复流程
    在这里插入图片描述
    奔溃后重启后会检测redo log中是完整并且处于prepare状态的事务,然后根据XID(事务ID),从binlog中找到对应的事务,如果找不到,则回滚;找到并且事务完整则重新commit redo log,完成事务的提交。

不同时刻MySQL奔溃后的恢复数据的流程:

  1. 时刻A:刚在内存中更改完数据页,还没有开始写redo log的时候奔溃
    因为内存中的脏页还没刷盘,也没有写redo log和binlog,即这个事务还没有开始提交,所以奔溃恢复跟这事务没有关系。
  2. 时刻B:正在写redo log或者已经写完redo log并且落盘后,处于prepare状态,还没有写binlog的时候奔溃。
    恢复后会判断redo log 的事务是不是完整的,如果不是则根据undo log回滚;如果是完整的并且是prepare状态,则进一步判断对应的binlog是不是完整的,如果不完整则一样根据undo log 进行回滚。
  3. 时刻C:正在写binlog或者已经写完binlog并且落盘了,还没有开始commit redo log时候奔溃
    恢复后跟时刻B一样,先检测redo log中事务是否完整并且处于prepare状态的事务,然后判断对应的事务binlog是不是完整,如果不完整一样根据undo log回滚,完整则重新commit redo log
  4. 时刻D正在commit redo log或者事务已经提交完的时候,还没有反馈成功给客户端的时候奔溃
    恢复时候跟时刻C一样,都会对照redo log和binlog的事务完整性,来确认是回滚还是重新提交。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值