MySQL 可以恢复到半个月内任意一秒的状态,这是为什么?
mysql的更新语句与查询语句大体相同,但多了两个日志模块即redo log(重做日志)和binlog(归档日志)
一、redo log和binlog
1、redo log模块(存储引擎层日志)
- WAL技术(Write-Ahead Logging)是InnoDB引擎先将“更新”写到redo log中并更新内存,这时候就算更新完毕了,等计算机“空闲”时再写入硬盘当中。
-
其中redo log是有固定大小的,等被写满时就不得不写入硬盘中了。也正因为有redo log的存在,所以在mysql发生异常重启后,InnoDB就可以记录不丢失,该能力被称为crash-safe。
2、binlog日志模块(server层日志)
3、两个日志模块联系与差异
mysql5.5.5以前默认使用自带的MyISAM引擎,该引擎没有crash-safe能力,只能依靠MyISAM进行归档;在 5.5.5 版本后使用InnoDB作为默认存储引擎。
差异处:
- redo log是InnoDB特有的,而binlog位于server层,所有引擎都可以使用;
- redo log是物理日志,记录了在实际物理位置进行的操作;binlog是逻辑日志,记录的是执行语句的原始逻辑;
- redo log是循环写,固定大小会被写完;binlog是追加写,写到一定大小切换到下一个,不覆盖以往内容。
二、update语句执行流程
注:下图中浅色在InnoDB中进行,深色在执行器中完成。
由上图可知,InnoDB中的操作被分成了两阶段提交,之所以要这样做,是因为只有一步的话,会导致一句日志回复的数据库状态与原数据库状态不同,这样在数据库发生崩溃和扩容时都带来巨大问题。这样做了可以保证redo log和binlog的逻辑一致。
tips:可以将mysql参数innodb_flush_log_at_trx_commit和sync_binlog这两个参数设为1,这样能保证数据库异常重启后物理日志和逻辑日志都不会丢失,因为已经被写到磁盘当中了。
网友评论