一条sql语句更新后,日志会做一些什么操作?
当一条sql语句被更新后,查询缓存就会失效,更新语句会把跟这个表的上的缓存都清除掉。
分析器知道这是一条sql语句,优化器使用索引优化等优化操作,执行器负责执行更新操作。
与查询流程不同,更新操作涉及2个重要的日志模块:
redo log (重做日志)和binlog(归档日志)
redo log
于是作者提出一个生动的说法,赊账,拿黑板记账,和没人账本记账,而黑板和账本的配合过程,
就是MySql里经常说的WAL(Write-Ahead Logging),关键点先写日志,再写磁盘,就是先写将redo log比作黑板,等不忙再写账本。
具体来说,当更新一条记录时,Innodb引擎先把记录写到redo log(黑板),再更新内存,这个时候更新就算完成。Innodb引擎会在适当时候,将 这个操作记录更新到磁盘里面,这个更新是系统空闲的时候才做,就好比酒店打烊。
但是,如果酒店人很多赊账,那么就是redo log记录数太多了,记录已满,这个时候酒店就会先拿账本把黑板中的记录下去,再擦除黑板,于是,Innodb的redo log 是固定大小的,比如可以配置一组4个文件,每个文件1G,这个redo log就能记录4G操作记录,从头开始写,写到末尾再从头写。(循环)。
同时,checkpoint和write pos 标志,wirte pos 记录当前的位置,一边写一边后移,写到3号文件末尾就回到0号文件,checkpoint是擦除当前要擦出的位置,也是往后推移并循环的,擦除记录前要把记录更新到数据文件。
write pos和checkpoint之间的是黑板上还空着的部分,可以用来记录新的操作,入偶股wirte pos追上checkpoint代表记录满了,这个时候不能再执行新的更新,得停下来擦掉一些记录,把checkpoint推进一下。
有了redo log,innodb可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,这个能力叫crash-safe。
binlog
mysql整体来看2层,一块server层,主要做mysql功能层面的事情,还有一块引擎层,负责存储相关的事宜,上面的redo log是Innodb引擎的特有日志,而server层也有自己的日志,称为binlog.
这2种日志的不同点:
1.redo log是innodb引擎特有的,binlog是mysql的server层实现的,所有引擎都能用。
2.redo log 是物理日志,记录的是“在某个数据页上做了什么修改”;binlog是逻辑日志,记录的是这个语句的原始逻辑
。“比如给某字段加2”。
3.redo log 是循环写,空间固定会用完,binlog是可以追加写入,追加写是指“binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。”