7 种日志文件:
一个很好的事务处理系统,必须具备这些标准特性:
利用WAL技术(Write-Ahead-Logging, 即先写日志,后写磁盘)推迟物理数据页的刷新,从而提升数据库吞吐,有效降低了访问时延。
redo log是InnoDB引擎特有的:binlog是MySQL的Service层实现的,所有的引擎都可以使用
redo log提供了crash-safe的能力,即使MySQL异常重启,之前提交的记录也不会丢失。
redo log是物理日志,记录的是在某一个数据页面上做了什么修改,binlog是逻辑日志,记录的是这个语句的原始逻辑
redo log是固定大小的,从头开始写,写到末尾之后又回头开头循环写,binlog是可以追加写当到达一定大小后会切换到下一个不会覆盖之前的日志
redo log的写入分成了 prepare 和 commit 两个阶段, 称为两阶段提交
redo log并不是直接写入磁盘的,而是先写入到缓存区,我们把这个缓冲区叫做 redo日志缓冲区
在 MySQL Server 5.7 下 redo日志缓冲区的大小默认为 1M,我们可以通过 innodb_log_buffer_size 参数来设置 redo 日志缓冲区的大小。
缓冲区和磁盘之间的数据如何同步?
在 MySQL配置文件中提供了 innodb_flush_log_at_trx_commit 参数,这个可以用来控制缓冲区和磁盘之间的数据如何同步:
我们使用默认值 1 就好,这样可以保证 MySQL 异常重启之后数据不丢失。
InnoDb 引擎会先将操作(更新)记录写到 redo log 中,并更新内存,此时就算更新完成了。InnoDb 引擎会在空闲或适当的时候将操作记录写到磁盘上


- 上图中画出了序号从0-3,共4个redo log
- write pos为当前写入位置, check point为检查点, write pos和check point都一直向前推进;write pos和check point之间的绿色部分就可以用来写入redo log
- checkpoint之前的所有数据都已经刷新回磁盘,当DB crash后,通过对checkpoint之后的redo log进行恢复就可以了
- 如果redo log过多, 此时check point还没有推进, write pos就追上了check point, 那么就必须等待check point向前推进, 此时MySQL无法处理更新操作

重做日志记录了事务的行为,可以很好的通过其对页进行“重做”操作。但是事务有时候还需要进行回滚操作,也就是ACID中的A(原子性),这时就需要Undo log了。因此在数据库进行修改时,InnoDB存储引擎不但会产生Redo,还会产生一定量的Undo。这样如果用户执行的事务或语句由于某种原因失败了,又或者用户一条ROLLBACK语句请求回滚,就可以利用这些Undo信息将数据库回滚到修改之前的样子。
Undo log是InnoDB MVCC事务特性的重要组成部分。当我们对记录做了变更操作时就会产生Undo记录,Undo记录默认被记录到系统表空间(ibdata)中,但从5.6开始,也可以使用独立的Undo 表空间。
Undo记录中存储的是老版本数据,当一个旧的事务需要读取数据时,为了能读取到老版本的数据,需要顺着undo链找到满足其可见性的记录。当版本链很长时,通常可以认为这是个比较耗时的操作。
undo log主要记录的是数据的逻辑变化,为了在发生错误时回滚之前的操作,需要将之前的操作都记录下来,然后在发生错误时才可以回滚。
undo log只将数据库逻辑地恢复到原来的样子,在回滚的时候,它实际上是做的相反的工作,比如一条INSERT ,对应一条 DELETE,对于每个UPDATE,对应一条相反的 UPDATE,将修改前的行放回去。undo日志用于事务的回滚操作进而保障了事务的原子性。
在InnoDB存储引擎中,undo存储在回滚段(Rollback Segment)中,每个回滚段记录了1024个undo log segment,而在每个undo log segment段中进行undo 页的申请,在5.6以前,Rollback Segment是在共享表空间里的,5.6.3之后,可通过 innodb_undo_tablespace设置undo存储的位置。
在InnoDB存储引擎中,undo log分为:insert undo log、update undo log
MySQL的主库(Master)对数据库的任何变化(创建表,更新数据库,对行数据进行增删改),都以二进制文件的方式记录与主库的Binary Log(即binlog)日志文件中。

statement 格式:SQL 语句
row 格式:行内容(记两条,更新前和更新后),推荐
从库的 IO Thread 异步地同步 Binlog 文件并写入到本地的 Replay 文件。SQL Thread 再抽取 Replay 文件中的 SQL 语句在从库进行执行,实现数据更新。 需要注意的是,MySQL Binlog 支持多种数据更新格式 – 包括 Row,Statement,或者 mix(Row 和 Statement 的混合)。我们建议使用 Row 这种 Binlog 格式(MySQL5.7 之后的默认支持版本),可以更方便更加实时的反映行级别的数据变化。

我们利用一些客户端工具 佯装 成 MySQL Slave,抽取出 Binlog 的日志文件,并把数据变化注入到实时的流式数据管道中。我们在管道后端对 Binlog 的变化日志,进行消费与必要的数据处理(例如利用AWS的Lambda服务实现无服务器的代码部署),同步到多种异构数据源中 – 例如 Redshift, ElasticSearch, S3 (EMR) 等等。具体的架构如下图所示。


mysql 的 innodb_flush_method 这个参数控制着 innodb 数据文件及 redo log 的打开、刷写模式,对于这个参数,文档上是这样描述的:
有三个值:fdatasync(默认),O_DSYNC,O_DIRECT
首先文件的写操作包括三步:open,write,flush
这三种模式写数据方式具体如下:


