实现的目标是,多进程的场景下,异步刷盘,同步确认。
1. 当有backend生成wal时,现在walbuffer上申请一段空间,然后将wal写入到这段空间中。
2. 为了最大限度使用tikv的吞吐能力,一般情况下,我们并不会在backend产生wal时,就立刻将wal写入到tikv中,而是当要写入的wal的连续长度超过8k时,才会批量刷盘。当然还要考虑一种特殊情况,就是虽然wal的连续长度没有达到要批量写入的标准,但是已经超出一定时间期限,这时候不管wal数据 有多少,都要执行刷盘操作。如下图所示。
XlogItem是用来记录刷盘时wal在walbuffer中位置长度当相关信息。XlogItemList是XlogItem的链表信息,方便批量刷盘。如下图所示。
3. 并不是每个backend都会亲自对本进程产生的wal进行刷盘。比如,backend1想将walbuffer中[100,200)空间上的数据进行刷盘,但是发现backend2要对[100,300)空间上的数据进行刷盘,那么backend1则什么都不做,让backend2来刷盘[100,300)的数据。
上述2和3是不同backend的异步刷盘的过程。
尽管有些wal已经刷盘,但并不意味着这些wal就是合法的wal。比如[0,100)以及[200,300)的wal已经刷盘了,但是[100,200)的wal还没有刷盘,那么[200,300)的wal就是无效的,当数据库重启的时候,无效的wal就要被删除掉。
所以同步确认所要达到的目的是,确认点之前的wal都是已经刷盘了的且连续的wal。同步确认的过程的一个例子:
a.[0,100)的wal刷盘成功,确认点为100;
b.[300,400)的wal刷盘成功,确认点为100;
c.[600,700)的wal刷盘成功,确认点为100;
d.[400,600)的wal刷盘成功,确认点为100;
e.[100,300)的wal刷盘成功,确认点为700;
局部变量curLoc和全局变量XLogCtl->LogFlush用来保证多进程间的同步确认。
XLogCtl->LogFlush.begin 和XLogCtl->LogFlush.last只是同步确认的逻辑序号,初始的时候都为0.




