WAL 机制是减少磁盘写,可是每次提交事务都要写 redo log 和 binlog,这磁盘读写次数也没变少呀?

  1. redo log 和 binlog 都是顺序写,磁盘的顺序写比随机写速度要快;
  2. 组提交机制,可以大幅度降低磁盘的 IOPS 消耗。

为什么 binlog cache 是每个线程自己维护的,而 redo log buffer 是全局共用的?

这么设计的主要原因是,binlog 是不能“被打断的”。一个事务的 binlog 必须连续写,因此要整个事务完成后,再一起写到文件里。

而 redo log 并没有这个要求,中间有生成的日志可以写到 redo log buffer 中。redo log buffer 中的内容还能“搭便车”,其他事务提交的时候可以被一起写到磁盘中。

事务执行期间,还没到提交阶段,如果发生 crash 的话,redo log 肯定丢了,这会不会导致主备不一致呢?

不会。因为这时候 binlog 也还在 binlog cache 里,没发给备库。crash 以后 redo log 和 binlog 都没有了,从业务角度看这个事务也没有提交,所以数据是一致的。

如果  sync_binlog = N,binlog_group_commit_sync_no_delay_count = M,binlog_group_commit_sync_delay = 很大值,这种情况 fsync 什么时候发生呀,min(N,M)吗?

达到 N 次以后,可以刷盘了,然后再进入(sync_delay 和 no_delay_count)这个逻辑;sync_delay 如果很大,就达到 no_delay_count 才刷。

如果  sync_binlog = 0,binlog_group_commit_sync_no_delay_count = 10,这种情况下是累计 10 个事务 fsync 一次?

只要  sync_binlog=0,也会有前面的等待逻辑,但是等完后还是不调 fsync。

有时候,sync_binlog = 0 或 =1 效果一样的原因

我说的 sync_binlog=0 或 =1 效果一样,就是看语句实际执行的效果,参数  binlog_group_commit_sync_delay  我设置成了 500000 微秒,在=1 或=0 时,对表进行 Insert,然后都会有 0.5 秒的等待,也就是执行时间都是 0.51 sec,关闭  binlog_group_commit_sync_delay,insert 执行会飞快,所以我认为=1 或=0 都是受组提交参数的影响的。