日志模块

redo log

InnoDB引擎实现

在MySQL里也有这个问题,如果每一次的更新操作都需要写进磁盘,然后磁盘也要找到对应的那条记录,然后再更新,整个过程IO成本、查找成本都很高

WAL技术,WAL的全称是Write-Ahead Logging,它的关键点就是先写日志,再写磁盘 顺序i/o

当有一条记录需要更新的时候,InnoDB引擎就会先把记录写到redo log里面,并更新内存,这个时候更新就算完成了。同时,InnoDB引擎会在适当的时候,将这个操作记录更新到磁盘里面

redo log是物理日志,记录的是“在某个数据页上做了什么修改”

InnoDB的redo log是固定大小的,比如可以配置为一组4个文件,每个文件的大小是1GB,总共就可以记录4GB的操作。从头开始写,写到末尾就又回到开头循环写。write pos是当前记录的位置,checkpoint是当前要擦除的位置也是往后推移并且循环的,擦除记录前要把记录更新到数据文件

有了redo log,InnoDB就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,这个能力称为crash-safe

bin log

Server层日志

binlog存在的原因 redolog只有InnoDB有,别的引擎没有,edolog是循环写的,不持久保存,binlog的“归档”这个功能,redolog是不具备的。

binlog是逻辑日志,记录的是这个语句的原始逻辑,比如“给ID=2这一行的c字段加1 ”,binlog文件写到一定大小后会切换到下一个,并不会覆盖以前的日志

  • statement:基于SQL语句的模式,某些语句中含有一些函数,例如 UUID NOW 等在复制过程可能导致数据不一致甚至出错。
  • row:基于行的模式,记录的是行的变化,很安全。但是 binlog 的磁盘占用会比其他两种模式大很多,在一些大表中清除大量数据时在 binlog 中会生成很多条语句,可能导致从库延迟变大。
  • mixed:混合模式,根据语句来选用是 statement 还是 row 模式。

两阶段提交

由于redo log和binlog是两个独立的逻辑,如果不用两阶段提交,数据库的状态就有可能和用它的日志恢复出来的库的状态不一致。

引擎将新数据更新到内存中,同时将更新操作记录到redo log里面,此时redo log处于prepare状态。然后告知执行器执行完成了,随时可以提交事务

执行器生成操作的binlog,并把binlog写入磁盘

行器调用引擎的提交事务接口,引擎把刚刚写入的redo log改成提交(commit)状态,更新完成

undo log

每条记录在更新的时候都会同时记录一条回滚操作。记录上的最新值,通过回滚操作,都可以得到前一个状态的值

当没有事务再需要用到这些回滚日志时,回滚日志会被删除,长事务会导致保存很多回滚日志占用大量存储空间