日志系统:一条SQL更新语句是如何执行的?| 青训营笔记

96 阅读2分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第三篇笔记。

redo log(重做日志)

  • 归属:InnoDB引擎特有的。
  • 类型:是物理日志,记录的是“在某个数据页上做了什么修改”。
  • 存储:是循环写的,空间固定会用完。

bin log(归档日志)

  • 归属:bin log是MySQL的Server层实现的,所有引擎都可以使用。
  • 类型:是逻辑日志,记录的是这个语句的原始逻辑,比如“给ID这一行的c字段加1”。
  • 存储:可以追加写入。“追加写”是指bin log文件写到一定大小后会切换到下一个,并且不会覆盖以前日志。

redo log为什么要分两段提交?

(1.写入redo log处于prepare阶段;2.提交事务处于commit状态)

答:为了让两份日志之间的逻辑一致性。

1.先写redo log后写bin log?

答:写了redo log 没写 bin log系统崩溃。实际的原表值已经修改(redo log)。但是逻辑日志(bin log没有记录)。如果利用bin log恢复就会变成未更改之前的数据

2.先写bin log后写redo log?

答:写了bin log没写redo log系统崩溃。实际的原表值未修改(redo log)。但是逻辑日志(bin log已经记录)。此时就造成两个日志不统一。 redo log用于保证crash-safe能力。innodb_flush_log_at_trx_commit这个参数设置成1的时候, 表示每次事务的redo log都直接持久化到磁盘。这个参数我建议你设置成1,这样可以保证 MySQL异常重启之后数据不丢失。 sync_binlog这个参数设置成1的时候,表示每次事务的binlog都持久化到磁盘。这个参数我也建 议你设置成1,这样可以保证MySQL异常重启之后binlog不丢失。 我还跟你介绍了与MySQL日志系统密切相关的“两阶段提交”。两阶段提交是跨系统维持数据逻辑 一致性时常用的一个方案,即使你不做数据库内核开发,日常开发中也有可能会用到。