上面总结了Mysql执行修改语句的过程,通过连接器-查询缓存-分析器-优化器-执行器-执行引擎几个部分。
也讲了修改语句的两阶段提交,
1-执行器把结果集写入执行引擎,
2-执行引擎把结果集写入内存,并登记redoLog,此时redoLog的状态是prepare,告诉执行器可以随时提交事物。
3-执行器把操作写入binLog,
4-执行器调用执行引擎,提交事物,把redoLog的状态改为commit
所以说,为什么要写两个日志,为什么要两个阶段提交。
首先比较一下redoLog和binLog的区别
1:binLog是逻辑日志,记录了set a= a+1; redoLog是物理日志,记录了在内存页22上进行了更新操作
2:binLog是循环链表,写到上次更新到磁盘的位置,会擦除旧日志,写入新日志。binLog在磁盘上会进行切分,日志文件到达一定大小之后,会新建文件对象,继续写入,日志不会丢失。
3:binLog是server层的,所有Mysql都可以用,但是redoLog是InnoDB引擎的,只能InnoDB自己使用。
所以当扩展库的时候,或者恢复数据的时候,会用binLog进行恢复,不会用redoLog
还有一个有意思的是,如果不设计成两阶段提交的话,在恢复数据的时候,会导致binLog日志的执行结果和redoLog的执行结果不匹配。比如
先写redoLog :update c=1 ok,再写binLog的日志 update c = 1时,系统坏掉了,恢复的时候,发现没有binLog的update c =1这个数据
如果先写 binLog update c =1 ok,再写redolog的时候,系统坏掉了,回复的时候发现,c =1 但是数据库里面的c!=1;