binlog 和redolog介绍
binlog
binlog cache
fsync
binlog的写入机制,事务执行过程中,先把日志写到binlog cache,事务提交的时候,再把binlog cache 写到binlog 文件
一个事务的binlog是不能被拆开的,因此不论事务多大,也要确保一次性写入,这就涉及到了binlog cache的保存问题
redo log
redolog buffer
page cache
fsync
后台线程每秒执行将redolog buffer中的日志,调用write写到文件系统的page cache,然后调用fsync持久化到磁盘,也是有可能事务没有提交之间,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里的日志一起持久化到磁盘
为了控制redolog的写入策略,innodb_flush_log_at_trx_commit参数,有三种可能取值
设置为0,每次提交事务时只是把redo log 留在redo log buffer中
设置为1,每次提交事务时直接将redo log 持久化到硬盘
设置为2,每次事务提交时只是把redo log 写到page cache
事务的两阶段提交,如果把innodb_flush_log_at_trx_commit设置成1,redo log会在prepare阶段就会持久化一次
通常我们说MySQL的双1配置,指的就是sync_binlog和innodb_flush_log_at_trx_commit都设置成1,也就是一个事务完成提交之前,需要等待两次刷盘,一次是redo log,一次是binlog
这样磁盘的IOPS很高,这时就用到了组提交,尽量等待多个并发事务的组成员,这样会提高效率
这样binlog也可以进行组提交,如果有多个事务的binlog已经写完了,也是一起持久化,这样可以减少IOPS的消耗
第三步会执行的很快,所以binlog的write和fsync间的间隔时间短,导致能够集合到一起持久化的binlog比较少,因此binlog的组提交效果没有redo log组提交的效果那么好
如果想要提升binlog组提交性能,可以通过设置binlog_group_commit_sync_delay和binlog_group_commit_sync_no_delay_count来实现
binlog_group_commit_sync_delay 表示延迟多少微秒后才调用fsync
binlog_group_commit_sync_no_delay_count 表示要积累多少次后才调用fsync
这两个是或的关系
WAL机制主要得益于两个方面
1.redolog和binlog都是顺序写,顺序写磁盘比随机写快
2.组提交机制,较少IOPS