WAL 机制是减少磁盘写,可是每次提交事务都要写 redo log 和 binlog,这磁盘读写次数也没变少呀?
- redo log 和 binlog 都是顺序写,磁盘的顺序写比随机写速度要快;
- 组提交机制,可以大幅度降低磁盘的 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 都是受组提交参数的影响的。