GaussDB关键技术原理——高性能之日志无锁刷新与多级流水

0 阅读1分钟

GaussDB关键技术原理——高性能之日志无锁刷新与多级流水

在写事务型负载中日志落盘位于性能关键路径,为了确保数据可靠性在执行INSERT、DELETE、UPDATE等操作均需要记录。经过在多核环境上的性能测试,我们发现日志在Flush时存在大量的等待,其本质原因是当前在并发场景下日志落盘环节中很难在WalInsertLock数量和锁遍历开销中取得平衡最优解,导致成为瓶颈。

在这里插入图片描述 上图展示了常见的日志的实现方案,主要可以归纳成3个方面:

(1)数据库内核线程必须获取日志插入锁WALInsertLock才能进入第一个临界区,在临界区中,Backend线程首先会预留WAL的插入位置,然后将生成的WAL复制到WAL Buffer的对应预留位置中。由于是多个数据库后台线程进行的并发拷贝,每个Backend线程拷贝完成的时机并不一致。

(2)数据库后台线程需要遍历所有的WALInsertLock检查lsn是否已经下盘,当WALInsertLock的数目越多时,在执行WAL Flush之前等待其他Backend线程将日志拷贝完成的时间就越长。

(3)WALInsertLock的数目越少时,XLog插入锁的抢占就越激烈。所以不管WALInsertLock的数量如何变化,系统的性能都很难达到最优,这成为了目前日志落盘的瓶颈。

在这里插入图片描述 GaussDB针对WalInsertLock日志锁进行优化,利用LSN(Log Sequence Number)及LRC(LogRecord Count)记录了每个backend的拷贝进度,取消WalInsertLock机制。在backend将日志拷贝至WalBuffer时,不用对WalInsertLock进行争抢,可直接进行日志拷贝操作。并利用专用的WalWriter写日志线程,不需要backend线程自身来保证xLog的Flush。通过以上优化,取消WalInsertLock争抢及WalWriter专用磁盘写入线程,在保持原有xLog功能不变的基础上,可进一步提升系统性能。针对Ustore Inplace update WAL log写入,Ustore DML operation并行回放分发进行优化。通过利用prefix和suffix来减少update WAL log的写入。通过把回放线程分多个类型,解决Ustore DML WAL大多都是多页面回放问题。同时把Ustore的数据页面回放按照blkno去分发,更好的提高并行回放的并行程度。