SQL更新语句的执行流程

本文详细介绍了MySQL中执行SQL更新语句的流程,涉及InnoDB的redo log和binlog。redo log通过WAL技术确保crash-safe,其刷脏页策略包括日志写满、系统内存不足或空闲时。binlog则是MySQL server层的日志,用于数据恢复和事务一致性。两阶段提交确保了redo log和binlog的一致性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

连接器-->分析器-->优化器-->执行器

更新流程还涉及两个重要的日志模块:redo log(重做日志)、binlog(归档日志)

redo log(InnoDB 特有的日志)

WAL技术:Write-Ahead Logging,先写日志,再写磁盘。即:当有一条记录需要更新的时候,InnoDB引擎就会先把记录写到redo log里更新内存,这个时候更新就算完成了。InnoDB引擎会在适当的时候(e.g.系统比较空闲的时候),将这个操作记录更新到磁盘里面(刷脏页)。

优点:保证即使数据库发生异常重启,之前提交的记录都不会丢失,即crash-safe。

平时执行很快的更新操作,其实就是在写内存和日志,刷脏页的过程由于会占用资源,可能会让你的更新和查询语句的响应时间长一些。MySQL偶尔“变慢”一下的那个瞬间,可能就是在刷脏页(flush)。

Q:什么时候将内存里的数据写入磁盘(flush)?

  1. InnoDB的redo log写满了。这时候系统会停止所有更新操作,把checkpoint往前推进,redo log留出空间可以继续写。
  2. 系统内存不足。当需要新的内存页,而内存不够用的时候,就要淘汰一些数据页,空出内存给别的数据页使用。如果淘汰的是“脏页”(内存数据页跟磁盘数据页内容不一致),就要先将脏页写到磁盘。
  3. MySQL认为系统“空闲”的时候。
  4. MySQL正常关闭的情况。这时候,MySQL会把内存的脏页都flush到磁盘上,这样下次MySQL启动的时候,就可以直接从磁盘上读数据,启动速度会很快。

(图片来自极客时间) 

刷脏页虽然是常态,但是出现以下这两种情况,都会明显影响性能:
1. 一个查询要淘汰的脏页个数太多,会导致查询的响应时间明显变长;
2. 日志写满,更新全部堵住,写性能跌为0,这种情况对敏感业务来说,是不能接受的。
所以,InnoDB需要有控制脏页比例的机制,来尽量避免上面的这两种情况。

InnoDB刷脏页的控制策略

InnoDB的刷脏页速度主要参考两个因素:一个是脏页比例,一个是redo log写盘速度。

InnoDB会根据这两个因素先单独算出两个数字,取其中大的值来控制刷脏页的速度。

binlog(SQL server层自己的日志)

不能实现crash-safe

两个日志比较

redo log是InnoDB特有的,binlog是MYSQL的server层实现的,所有引擎都可以使用;

redo log是循环写,固定空间会用完;binlog是追加写,不会覆盖以前的日志;

redo log是物理日志,binlog是逻辑日志;

执行一条更新语句的流程

(图来自极客时间)

数据恢复过程:找到最近一次全量备份,恢复到临时库;从备份的时间点开始,将备份的binlog依次取出来进行操作;把数据从临时库恢复到线上库

两阶段提交:如果不使用“两阶段提交”,那么数据库的状态就有可能和用它的日志恢复出来的库的
状态不一致。

总结:redo log和binlog都可以用于表示事务的提交状态,而两阶段提交就是让这两个状态保
逻辑上的一致

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值