MYSQL 一个事务在提交的时候能够保证binlog和redo log是同时提交的,并且能在宕机恢复后保持binlog 和redo log的一致性。

先来看看什么是redo log 和binlog,以及为什么要保持它们的一致性。

什么是redo log,binlog

redo log
是innodb引擎层产生的日志, MYSQL从磁盘读取数据的单位是一页,当修改页中某条数据时,该行所在的数据页就变成了
脏页
,由于脏页并不会立马刷新到磁盘,所以
redo log会记录下数据页进行了哪些变动,用于服务崩溃时的数据恢复
。redo log是固定大小的,由多个文件组成一个环形的结构,

image.png

redo log由两个指针,write pos 和checkpoint,都是顺时针移动,write pos 记录redo log当前写入的位置, checkpoint往前移动,就代表就移动过的redo log记录的脏页刷新到磁盘上。所以,
write pos

checkpoint
之间的位置就代表redo log 还可以写的空间大小,当write pos等于checkpoint时,MYSQL则必须等待脏页刷新完毕后才能继续进行修改操作。

binlog
是mysql server服务层产生的日志。两者的用途也不一样。
binlog
则主要用于数据库的备份,主从同步。binlog记录的是行变化,记录格式也有3种,statement,row,mixed,这里就不细讲了。

在了解了redo log 和binlog的含义和各自的作用后,我们先来看看它们在一次sql更新中是如何运作的。

sql 更新过程详解

来看下在一次事务过程中,它们的工作机制。假设我们在进行修改操作,那么可以用下面的流程图来表示,

image.png

1
,首先判断要修改的数据是否在内存里,没有的话就从磁盘读取到内存。

2
,写入redo log,注意这里写入的redo log仅仅是prepare状态,只有等到正式提交的时候才会变成commit状态。并且写入redo log也不是直接落盘,其实是写入到了
redo log buffer
中,落盘时机受到
innodb_flush_log_at_trx_commit
参数控制。

MYSQL会有一个后台线程,定时刷新redo log buffer 中的数据到磁盘上。除此以外,当
innodb_flush_log_at_trx_commit 值为1
时 redo log则会在在prepare阶段将redo log buffer 中的数据落入磁盘。



注意

标签: none

添加新评论