首先我们需要知道两个概念
缓冲池(buffer pool):主内存中的一个区域,里面可以缓存磁盘上经常操作的真实数据,在执行增删改查操作时,先操作缓冲池中的数据(若缓冲池没有数据,则从磁盘加载并缓存),以一定频率刷新到磁盘,从而减少磁盘IO,加快处理速度
数据页(page):是InnoDB 存储引擎磁盘管理的最小单元,每个页的大小默认为 16KB。页中存储的是行数据
当我们在mysql中更新数据,我们操作的是mysql中的数据,为了提升性能我们引入了两块区域,一块是内存结构,一块是磁盘结构
其中磁盘结构主要存储的就是数据页,比如某一个表的ibd文件,就包含了很多数据页,每个页就存储着我们表中一行一行的数据,
当我们去操作数据的时候,并不会直接操作磁盘,而是会先操作内存,也就是缓存池。当操作进来了,会先从buffer pool里找一找有没有需要的数据,如果没有就会把磁盘中的数据加载到内存中,也就是把某一页的数据存储到缓存池中。
当我们操作结束了,它会按一定的频率把数据同步到磁盘中,这样可以减少磁盘io,加快处理速度,但是在内存中的数据,如果还没存储到磁盘中时,此时他叫做脏页,我们需要把他同步到磁盘中后,这个数据才算是真正的持久化了,但是如果此时服务器宕机了,那内存中的数据就有可能会发生丢失,
为了避免这种情况,于是在MySQL中引入了一种日志文件叫做redo log
redo log
重做日志,记录的是事务提交时数据页的物理修改,是用来实现事务的持久性。
该日志文件由两部分组成:重做日志缓冲(redo log buffer)以及重做日志文件(redo log file),前者是在内存中,后者在磁盘中。当事务提交之后会把所有修改信息都存到该日志文件中, 用于在刷新脏页到磁盘,发生错误时, 进行数据恢复使用。
当发生增删改的时候,在redo log buffer中就会记录数据页的变化,一旦它发生了变化,就会同步的把这些数据记录到磁盘文件中也就是redo log file。如果数据同步失败就会从redo log日志中来恢复数据
那我们不用redo log,我们直接把数据进行同步不行吗?可以,但是这样会有严重的性能问题,因为大量的增删改操作,在我们保存到磁盘中时,都是随机的磁盘io,这个性能是非常低的。而使用redo log在进行数据同步的时候是顺序的磁盘io,因为日志文件都是追加的,所以性能就会提升很多,并且redo log日志是会定期清理的,同时因为在磁盘中有两份,这样就能方便使用
简单概括:当刷新脏页数据到磁盘时,加入发生错误,可以使用redo log进行数据的恢复,从而实现数据的持久性
undo log
回滚日志,用于记录数据被修改前的信息 , 作用包含两个 : 提供回滚 和 MVCC(多版本并发控制) 。
undo log和redo log记录物理日志不一样,它是逻辑日志。
可以认为当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然,
当update一条记录时,它记录一条对应相反的update记录。
当执行rollback时,就可以从undo log中的逻辑记录读取到相应的内容并进行回滚。
undo log可以实现事务的一致性和原子性
面试回答
面试官:undo log和redo log的区别
候选人:好的,其中redo log日志记录的是数据页的物理变化,服务宕机可 用来同步数据,而undo log 不同,它主要记录的是逻辑日志,当事务回滚 时,通过逆操作恢复原来的数据,
比如我们删除一条数据的时候,就会在 undo log日志文件中新增一条delete语句,如果发生回滚就执行逆操作; redo log保证了事务的持久性,undo log保证了事务的原子性和一致性