WAL机制的延伸

  • binlog的写入流程
  • redolog写入流程
  • 另外两种让一个没有提交的事务写入到磁盘的场景
  • 组提交机制
  • 小结


binlog的写入流程

1. 事务执行过程中,先把日志写到binlog cache
2. 事务提交的时候,再把binlog cache写到binlog文件中

注意点:
一个事务的binlog是不能被拆分的,因此不论这个事务多大,也要确保一次性写入,这就涉及到binlog cache的保存问题

系统给binlog cache分配了一片内存,每个线程一个,参数binlog_cache_size用来控制单个线程内binlog cache所占内存的大小,如果超过了这个参数规定的大小,就要暂存到磁盘

事务提交的时候,执行器把binlog cache里的完整事务写入到binlog 中,并清空binlog cache

每个线程都有自己的binog cache,把数据从binlog cache缓存到磁盘会经历两个阶段:

  1. 一个是将binlog cache里面的内容使用write写入到文件系统中的page cache(write)
  2. 另一个是把page cache里面的binlog写入到磁盘(fsync)

write和fsync的时机,是由参数sync_binlog控制的
1. sync_binlog = 0时,表示每次提交事务都只write,不fsync
2. sync_binlog = 1时,表示每次提交事务都会fsync
3. sync_binlog = N时,表示每次提交事务都只write,累积N个事务后进行fsync

redolog写入流程

问题:
	事务执行的过程中,生成的redo log 是要先写到redo log buffer中的,那么redolog buffer里面的内容,是不是每次都要持久化到磁盘呢?
答案是: 不需要


那么,另外一个问题是,事务还没有提交的时候,redolog buffer中的部分日志有没有可能被持久化到磁盘呢
答案是: 有可能

redolog可能存在的三种状态:

1. 存在redolog buffer中
2. 写到磁盘(write),但是还是没有持久化
3. 持久化到磁盘

为了控制redolog的写入策略,InnoDB提供了innodb_flush_log_at_trx_commit参数,他有三种取值:

1. 设置为0的时候,表示每次事务提交只是把redolog保存在redolog buffer中
2. 设置为1的时候,表示每次事务1提交时都将redolog直接持久化到磁盘
3. 设置为2的时候,表示每次事务提交时都只是把redolog写入到page cache

InnoDB在后台维护了一个后台线程,每隔一秒就把redolog buffer里面的文件刷进page cache,然后进行fsync写入到磁盘,这里有一个注意的点,就是还没有提交的事务的redolog也会写入到redolog buffer,所以当刷磁盘的时候,有可能会把还没有提交的事务的redolog给刷进去,造成binlog和redolog不一致的情况

另外两种让一个没有提交的事务写入到磁盘的场景

  1. redolog buffer占了innoDB_buffer_size一半的时候。这个时候后台线程会主动写盘
  2. 并行的事务提交的时候,顺带将这个未提交事务的redolog写入到磁盘,线程A事务完成要提交redolog buffer,线程B事务未提交写了一半的redolog buffer,被线程A给直接提交了

注意点:

如果把innodb_flush_log_at_trx_commit设置为1,那么redolog在prepare阶段就要持久化一次

双1配置:

指的就是innodb_flush_log_at_trx_commit和sync_binlog都设置成1,在事务提交前,要经过两次刷盘

组提交机制

双1的问题:
如果从mysql看到的TPS是两万的话,每秒就会写4万次磁盘,但是,用工具测出来,磁盘能力也就两万左右,怎么能实现两万的TPS

日志逻辑序列号(LSN):
LSN是单调递增的,用来对应redo log的一个个写入点,每次写入长度为length的redolog,LSN的值就会加上length,LSN也会写入到InnoDB的数据页中,来确保数据页不会被多次执行重复的redolog

redolog的prepare实际上是被拆成了两部分,为了延迟时间,提升组提交的效率
binlog的写入也和redolog的prepare的两部分混合在一起,一起使用组提交

mysql如何保证唯一 mysql如何保证不丢数据_后台线程

小结

主要总结了如何保证redolog和binlog是否完整的问题,他们各自的write和fsync的时机,保证fsync的时机,以及组提交等机制