📝个人主页:五敷有你
🔥系列专栏:面经
⛺️稳中求进,晒太阳
redo log(重做日志)
重做日志(是物理日志),记录的是事务提交时数据页的物理修改,是用来实现事务的持久性。
该日志文件由两部分组成:重做日志缓冲(redo log buffer)以及重做日志文件(redo log file),前者是在内存中,后者在磁盘中。当事务提交之后会把所有修改信息都存到该日志文件中, 用 于在刷新脏页到磁盘,发生错误时, 进行数据恢复使用。
如果没有redo log会怎样?
在Innodb引擎中的内存结构中,主要的内存区就是缓冲池Buffer Pool,在缓冲池中缓存了许多数据页。
当我们在一个事务中执行多个增删改的操作时,InnoDB引擎会先操作缓冲池中的数据。如果缓冲池中没有对应数据,会通过后台线程将磁盘中的数据加载出来,放在缓冲区中,然后将缓冲池的数据进行修改,修改后的数据页称之为脏页。
而脏页则会在一定的时机,通过后台线程刷新到磁盘中,从而保证缓冲池和磁盘的数据页的数据一致。而缓冲区的脏页并不是实时刷新的,而是一段时间后将缓冲区的数据刷新到磁盘中,加入刷新到磁盘的过程中出错了,而提示用户数据提交完成,数据却没有持久化下来,就会出大问题的。没有保证事务的持久性。
那么,如何解决上述的问题呢? 在InnoDB中提供了一份日志 redo log,接下来我们再来分析一 下,通过redolog如何解决这个问题。
有了redo log日志之后,缓冲池的数据先要同步到Redolog缓冲中,在事务提交时,会将redo log buffer中的数据刷新到redo log磁盘文件中。过一段时间之后,如果刷新缓冲区的脏页到磁盘时,发生错误,此时就可以借助于redo log进行数据 恢复,这样就保证了事务的持久性。 而如果脏页成功刷新到磁盘 或 或者涉及到的数据已经落盘,此 时redolog就没有作用了,就可以删除了,所以存在的两个redolog文件是循环写的。
那么有一个问题就是为什么每一次提交事务要刷新redo Log到磁盘呢,而不是直接将buffer pool的脏页直接刷新到磁盘中呢?
因为在业务操作中,我们的操作数据一般都是随机读写磁盘,而不是顺序读写磁盘。而redo log在磁盘中写入数据,由于是日志文件,所以都是顺序读写,顺序写的效率要远大于随机,这种先写日志的方式,称之为WAL (Write-Ahead Logging)
undo log日志(逻辑日志)
回滚日志,用于记录数据被修改前的信息,作用包含两个,提供回滚(保证原子性)和MVCC(多版本并发控制)。
undo log和redo log 记录的物理日志不一样,他是逻辑日志,可以认为当delete一条数据时,undo log会记录一条对应的insert记录,反之亦然,当update一条记录时,他记录一条与之相反的update记录,当执行rollback时,就可以从undo log中的逻辑记录读取到相对应的内容并进行回滚。
Undo log销毁:undo log在事务执行时产生,事务提交时,并不会立即删除undo log,因为这些 日志可能还用于MVCC。
MVCC 的实现依赖于:
隐藏字段、Read View、undo log。在内部实现中,InnoDB 通过数据行的 DB_TRX_ID(事务id) 和 Read View 来判断数据的可见性,如不可见,则通过数据行的 DB_ROLL_PTR(回滚指针) 找到 undo log 中的历史版本。每个事务读到的数据版本可能是不一样的,在同一个事务中,用户只能看到该事务创建 Read View 之前已经提交的修改和该事务本身做的修改
bin log
相当于SQL的二进制版本,保存的SQL的二进制格式,通常可以使用my2sql来实现数据回滚,叫前滚的SQL语句。
可以说MySQL
数据库的数据备份、主备、主主、主从都离不开binlog
,需要依靠binlog
来同步数据,保证数据一致性。
binlog
会记录所有涉及更新数据的逻辑操作,并且是顺序写。