MySQL写入binlog和redo log的流程

只要redo log和binlog保证持久化到了磁盘,就能确保MySQL异常重启后,数据可以恢复。

binlog的写入机制

binlog的写入逻辑是:事务执行过程中,先把日志写到binlog cache,事务提交的时候,再把binlog cache写到binlog文件中。

一个事务的binlog是不能被拆开的,因此不管这个事务多大,也要确保一次性写入,因此,系统给binlog cache分配了一片内存,每个线程一个,参数binlog_cache_size用于控制单个线程内binlog cache所占内存的大小,如果超过了这个参数规定的大小,就要暂存到磁盘。事务提交的时候,执行器把binlog cache里的完整事务写入到binlog中,并清空binlog cache。

MySQL写入binlog和redo log的流程_第1张图片从上图中可以看到,每个线程都有自己的binlog cache,但是共用同一份binlog文件。

  • 上图中的write,指的就是把日志写入到文件系统的page cache,并没有把数据持久化到磁盘,所以速度比较快。

  • 上图中的fsync,才是将数据持久化磁盘的操作。一般情况下,认为fsync才占磁盘的IOPS。

write和fsync的时机,由参数sync_binlog控制:

  • 1、sync_binlog=0,表示每次提交事务都只write,不fsync

  • 2、sync_binlog=1,表示每次提交事务都会执行fsync

  • 3、sync_binlog=N(N>1),表示每次提交事务都write,但累积N个事务之后才fsync

比较常见的场景是将sync_binlog设置为100~1000中的某个值。

redo log的写入机制

MySQL写入binlog和redo log的流程_第2张图片MySQL redo log的存储状态

如上图所示,这三种状态分别是:

1、红色部分:存在redo log buffer中,物理上是在MySQL进程内存中

2、黄色部分:写到磁盘(write),但是没有持久化(fsync),物理上是在文件系统的page cache中。

3、绿色部分:持久化到磁盘,对应的是hard disk。

日志写到redo log buffer是很快的,写到page cache也差不多,但是持久化磁盘的速度就慢多了。

redo log的写入策略,可以通过innodb_flush_log_at_trx_commit参数进行控制:

1、值为0,表示每次事务提交时都只是把redo log留在redo log buffer中;

2、值为1,表示每次事务提交时都将redo log直接持久化到磁盘;

3、值为2,表示每次事务提交时都只是把redo log写到page cache。

InnoDB有一个后台线程,每隔1秒,就会把redo log buffer中的日志,调用write写到文件系统的page cache中,然后调用fsync持久化到磁盘。

这里需要注意,事务执行中间过程的redo log也是直接写在redo log buffer中的,这些redo log也会被后台线程一起持久化到磁盘。也就是说,一个没有提交的事务的redo log,也是可能已经持久化到磁盘的。

实际上,除了后台线程每秒一次的轮询操作外,还有两种场景会让一个没有提交的事务的redo log写入到磁盘中。

1、一种是,redo log buffer占用的空间即将达到 innodb_log_buffer_size一半的时候,后台线程会主动写盘。注意,由于这个事务并没有提交,所以这个写盘动作只是write,而没有调用fsync,也就是只留在了文件系统的page cache。

2、另一种是,并行的事务提交的时候,顺带将这个事务的redo log buffer持久化到磁盘。假设一个事务A执行到一半,已经写了一些redo log到buffer中,这时候有另外一个线程的事务B提交,如果innodb_flush_log_at_trx_commit设置的是1,那么按照这个参数的逻辑,事务B要把redo log buffer里的日志全部持久化到磁盘。这时候,就会带上事务A在redo log buffer里的日志一起持久化到磁盘。

通常我们说MySQL的“双1”配置,指的就是sync_binlog和innodb_flush_log_at_trx_commit都设置成 1。也就是说,一个事务完整提交前,需要等待两次刷盘,一次是redo log(prepare 阶段),一次是binlog。

正文止。

感兴趣的朋友,欢迎关注我的公众号哈,公众号上已经集成了AI大模型,大家可以过来聊天、问问题了

MySQL写入binlog和redo log的流程_第3张图片

你可能感兴趣的:(mysql,数据库)