数据库日志 | 青训营笔记

128 阅读3分钟

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

redo log 事务日志、重做日志

恢复到丢失的修改

InnoDB独有,为MySQL提供了崩溃恢复能力

  • MySQL中数据以页为单位
  • 查询或者修改数据时,会从硬盘加载一个数据页到Buffer Pool
  • 查询或修改会在Buffer Pool中进行,如果没有命中数据再去硬盘加载,以减小IO开销
  • 然后会把“在某个数据页上做了什么修改”记录到重做日志缓存(redo log buffer),接着刷盘到redo log文件

redo log buffer 刷盘时机

innodb_flush_log_at_trx_commit:

  • 0:每次事务提交时不刷盘
  • 1:每次事务提交时刷盘,默认
  • 2:每次事务提交时写到文件系统page cache

image.png

进入了redo log buffer,会受到MySQL和物理机影响

进入了page cache,只会受到物理机宕机影响

事务提交即刷盘,不会有数据损失

redo log 日志文件组

多个文件组成循环队列,write pos``记录下一个可写的位置,checkpoint`记录上次擦除后的位置

每次MySQL加载redo log恢复数据时,会擦除加载过的记录;当队列首尾相遇时,会擦除一些记录。

image.png

binlog 二进制日志、归档日志

redo log是物理日志,记录“在某个数据页上做了什么修改”。属于存储引擎。

binlog是逻辑日志,记录语句的原始逻辑,如给xxx加1。属于MySQL server层,所以不管用什么引擎,发生了表数据更新,都会产生日志。数据库集群通过binlog 同步数据

binlog会顺序记录所有使数据更新的逻辑操作。

记录格式

  • statement:记录SQL语句原文
  • row :记录原文及具体数据, 需要通过工具导出查看
  • mixed :折中手段,系统判断记录语句会导致不一致,就选择row格式

写入机制

事务执行中 → binlog cache → 事务提交 → binlog

sync_binlog:

  • 0:提交事务只wirte,系统决定fsync时机,默认
  • 1:提交事务会fsync刷盘
  • N:通常只write,累计提交N个事务后fsync刷盘

同上,主机宕机会丢失page cache,MySQL挂了会丢失binlog cache

image.png

两阶段提交

redo log作用:崩溃恢复的保障;写入时机:伴随着事务过程写入。

binlog作用:数据库集群同步数据;写入时机:事务提交写入。

引出问题:redo log在事务未完成时写入了数据更新,但提交出了错,更新没有写入binlog,那么主数据库从redolog恢复数据得到了更新,而从数据库从binlog同步数据而没有得到更新。数据不一致。

解决问题:redo log侧将写入拆成preparecommit,InnoDB两阶段提交。

image.png

prepare阶段的日志,如果binlog中找不到对应事务id不会用来恢复。

undo log 回滚日志

回滚到修改之前

提供事务的原子性

事务进行的修改会先记录到undolog中,且这个记录先于具体数据的持久化

回滚时能通过记录的数据旧值回滚