MySQL-redo log

230 阅读2分钟

InnoDB更新数据:

修改数据时,不可能每个修改都直接更新到磁盘进行持久化,因为大量并发修改时,这样会导致大量的随机IO,效率非常低。

因此用buffer pool,来表示数据库页面在内存中的缓存。在发生修改时,会先在buffer pool上进行,标记为dirty。后续将会有专门的线程,阶段性的将脏页刷到磁盘,完成真正意义上的数据修改。(大量随机IO转化为顺序IO,在合适的时候才去进行随机IO)

异常时,如何保证dirty page的更新持久化?

内存中的dirty page是易失性的,在宕机时,需要通过手段来保证数据不会丢失。

解决办法就是将所有对物理页的修改,写入一个文件进行持久化。在异常发生的时候,可以根据这个文件进行恢复。这个文件就是redo log file。

这种做法,称为预写日志:write ahead logging(WAL)。赋予了数据库crash safe的能力。

redo log带来的优势

  • 写buffer pool,写redo log,将大量随机IO转化为顺序IO。
  • WAL机制保证了持久性。

redo log的结构

采用循环写的模式。空间有限,通过两个指针移动(p1指向待写入位置,p2指向待擦除位置),去循环使用空间。

参数

innodb_flush_log_at_trx_commit={0|1|2}

  • 0:log buffer将每秒一次地写入log file中,并且log file的flush(刷到磁盘)操作同时进行。该模式下在事务提交的时候,不会主动触发写入磁盘的操作。
  • 1:每次事务提交时MySQL都会把log buffer的数据写入log file,并且flush(刷到磁盘)中去,该模式为系统默认。
  • 2:每次事务提交时MySQL都会把log buffer的数据写入log file,但是flush(刷到磁盘)操作并不会同时进行。该模式下,MySQL会每秒执行一次 flush(刷到磁盘)操作。