Mysql 日志模块:redo log(重做日志)和binlog(归档日志)

redo log(InnoDB)

  • 如果每一次更新都写磁盘,然后磁盘也要找到对应记录,再更新,整个过程的IO成本和查找成本都很高。所以InnoDB采取WAL(Write-Ahead Logging)技术,即先写日志,再写磁盘。
  • 当有记录需要更新时,InnoDB引擎先记录redo log,再更新内存。然后找适当时机将该操作写到磁盘(比如系统空闲时)。
  • redo log的大小是固定的(可配置),比如4个文件,每个文件大小1GB,从第一个文件开始写,写到第四个文件末尾再从头循环。
  • 图片来自Mysql45讲02图片来自Mysql45讲02
  • write pos是当前写到哪里了,check point是当前擦除到哪里了(擦除之前要把记录更新到数据文件),两者间绿色部分是可以写的空间。如果write pos追上了check point,则不能再执行新的更新操作,得先擦除一些记录。
  • 有了redo log,InnoDB可以保证数据库异常重启,之前提交的记录也不会丢失,这个能力称为crash-safe

binlog

  • redo log是InnoDB引擎特有的,而binlog属于Server层。
  • 最初Mysql自带引擎是MyISAM,但是该引擎没有crash-safe能力,binlog只能用于归档。

两者不同点

  • 如上所述,redo log是InnoDB特有,binlog所有引擎都可使用(因为所有引擎共用Server层)。
  • redo log是物理日志,记录的是某数据页做了什么修改;binlog是逻辑日志,记录的是语句的原始逻辑,比如给ID=2这一行的c字段加1
  • redo log是循环写的,空间固定会用完(用完后需要擦除记录才能写新的);binlog是追加写,单个文件达到一定大小会切换到下一个,不会覆盖旧的。

更新语句流程

update T set c=c+1 where ID=2;

  • 执行器先找到ID=2这一行,ID是主键,引擎用树搜索找到这一行。如果该行所在数据页本来就在内存中,就直接返回给执行器。否则,需要先从磁盘读入内存,再返回。
  • 执行器拿到引擎给的行数据,把c字段的值加1,得到新的行数据,再调用引擎接口写入这行新数据。
  • 引擎将这行新数据更新到内存中,并同时写入redo log,此时redo log处于prepare状态,然后告知执行器执行完成了,随时可以提交。
  • 执行器生成这个操作的binlog,并把binlog写入磁盘。
  • 执行器调用引擎的提交事务接口,引擎把刚刚写入的redo log改为commit状态,更新完成。
  • 图片来自Mysql45讲02,深色代表Server层,浅色代表InnoDB。
    在这里插入图片描述

两阶段提交

  • 为什么必须有两阶段提交?是为了让两份日志之间逻辑一致。
  • binlog会记录所有逻辑操作,恢复数据时可以采用A时间点全量数据+A时间点后binlog的方式。
  • redo log 和 binlog 都可以用于表示事务的提交状态,而两阶段提交就是让这两个状态保持逻辑上的一致。

配置

  • innodb_flush_log_at_trx_commit 这个参数设置成 1 的时候,表示每次事务的 redo log 都直接持久化到磁盘,这样可以保证 MySQL 异常重启之后数据不丢失。
  • sync_binlog 这个参数设置成 1 的时候,表示每次事务的 binlog 都持久化到磁盘,这样可以保证 MySQL 异常重启之后 binlog 不丢失。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值