12°

MySQL日志系统

在MySQL基础架构中,我们通过查询流程了解了MySQL的基础架构;本篇我们将通过更新流程了解MySQL的两个重要日志模块:重做日志和归档日志。

重做日志(redo log)

MySQL使用了WAL(Write-Ahead Logging)技术提升了MySQL的更新效率:当有一条记录需要更新时,InnoDB引擎先将更新记录写入redo log中并更新内存,此时更新操作就算完成;然后在适当的时候再将redo log中的操作记录更新到磁盘中。

InnoDB的redo log是固定大小;write pos是当前操作记录的位置,checkpoint为需要擦除的位置。

write pos和checkpoint之间的是空余部分,用来记录新的操作记录;当write pos追上checkpoint时表示redo log已满,此时不能再执行新的更新,需要先将一些操作记录更新到磁盘中推进checkpoint。

有了redo log,即使数据库发生异常重启,之前提交的记录都不会丢失;即crash-safe

归档日志(bin log)

上面的redo log是存储引擎层InnoDB引擎特有的日志,而Server层也有自己的日志即binlog日志。

  • redo log是InnoDB引擎特有的;而binlog是MySQL的Server层独有的,所有引擎都可使用;
  • redo log是物理日志,记录的是”在某个数据页上做了什么修改“,;而binlog是逻辑日志,记录的是语句的原始逻辑;
  • redo log是循环写的,空间固定会用完;binlog是追加写入,写到一定大小后会切换到下一个,并不会覆盖以前的日志。

两个日志系统对更新的操作

例如执行update t_user set age = age + 1 where id = 2

  • 执行器先找引擎读取id为2的这一行数据,引擎使用树搜索找到这一行数据:如果内存中存在,直接返回数据;否则从磁盘中找到这一行数据读入内存再返回。
  • 执行器在原数据上将age+1后,调用引擎写入新数据。
  • 引擎将数据更新到内存中,并将操作记录到red log中,此时red log处于prepare状态。然后通知执行器执行完成,可以提交事务了。
  • 执行器生成操作的binlog,并将binlog写入磁盘中。
  • 执行器调用引擎的提交事务接口,引擎将刚刚写入的red log改成commit状态,更新完成。

两阶段提交

通过上面示例可知redo log的写入分成两部分:prepare和commit,即”两阶段提交“。 如果不使用两阶段提交,无论先写哪个log都可能导致数据的不一致。

数据恢复

系统定期做整库备份,当需要恢复到特定时间t的时候:

  • 首先找到t之前的最近一次整库备份,将这个备份恢复到临时库;
  • 将备份时间与恢复时间t之间binlog取出来,重新执行到t的时刻。

此时临时库就是恢复到时间t的数据库了。

本文由【哥哥曾啊】发布于开源中国,原文链接:https://my.oschina.net/qgmzzmn/blog/3157896

全部评论: 0

    我有话说: