连接器-->分析器-->优化器-->执行器
更新流程还涉及两个重要的日志模块:redo log(重做日志)、binlog(归档日志)
redo log(InnoDB 特有的日志)
WAL技术:Write-Ahead Logging,先写日志,再写磁盘。即:当有一条记录需要更新的时候,InnoDB引擎就会先把记录写到redo log里更新内存,这个时候更新就算完成了。InnoDB引擎会在适当的时候(e.g.系统比较空闲的时候),将这个操作记录更新到磁盘里面(刷脏页)。
优点:保证即使数据库发生异常重启,之前提交的记录都不会丢失,即crash-safe。
平时执行很快的更新操作,其实就是在写内存和日志,刷脏页的过程由于会占用资源,可能会让你的更新和查询语句的响应时间长一些。MySQL偶尔“变慢”一下的那个瞬间,可能就是在刷脏页(flush)。
Q:什么时候将内存里的数据写入磁盘(flush)?
- InnoDB的redo log写满了。这时候系统会停止所有更新操作,把checkpoint往前推进,redo log留出空间可以继续写。
- 系统内存不足。当需要新的内存页,而内存不够用的时候,就要淘汰一些数据页,空出内存给别的数据页使用。如果淘汰的是“脏页”(内存数据页跟磁盘数据页内容不一致),就要先将脏页写到磁盘。
- MySQL认为系统“空闲”的时候。
- 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都可以用于表示事务的提交状态,而两阶段提交就是让这两个状态保
持逻辑上的一致。