中文
注册

原理介绍

在MySQL OLTP场景下,大量并发的DML语句(Insert, Update, Delete)会访问trx_sys全局结构体中的关键数据结构,导致出现临界区竞争和同步瓶颈。为了解决这个问题,鲲鹏BoostKit对MySQL事务管理器进行了改造,如图1所示,使用无锁哈希表来维护事务单元,读写场景下使用同步锁机制实现事务隔离级别和多版本控制,从而减少锁冲突,提高并发度。

图1 MySQL无锁优化特性实现原理

由于MySQL的事务管理器使用链表、数组等数据结构维持全局的事务记录。Trx-sys是MySQL中的一个全局实例,维护事务系统的各种信息,例如几种事务对象的容器。

  • rw_trx_list:包含读写事务实例,用链表实现。
  • mysql_trx_list:包含所有用户线程事务实例,用链表实现。
  • rw_trx_ids:包含读写事务id,用于快速拷贝一个快照,用std::vector实现。
  • rw_trx_set:事务id到事务对象的映射,用于通过trx_id快速找到事务实例,用std::set实现。

这些容器本身并不是线程安全的,并且有时需要对Trx-sys里多个数据(包括这些容器和其他数据)进行同步操作。原始代码中使用Trx-sys->mutex实现这一目的。例如trx_set_rw_mode要将一个事务设置为读写事务时:

在高并发写的场景下,系统中存在大量读写事务相关操作,对Trx-sys->mutex的竞争开始形成吞吐量瓶颈。

在Trx-sys->mutex保护的 临界区 中各类操作中,我们通过profiling识别出两个主要耗时操作:rw_trx_set.insert和rw_trx_set.erase。rw_trx_set是std::set,底层实现通常是某类平衡树,通过原始代码中的注释可以看出原作者也尝试过std::unordered_set。我们的测试也显示std::unordered_set在这里并没有性能优势。

在本特性中,我们采用无锁哈希对象rw_trx_hash来替代rw_trx_set的功能,从而显著减小Trx-sys->mutex临界区耗时,缓解Trx-sys->mutex竞争,提升系统吞吐量。MySQL本身已经在performance schema和MDL中使用过无锁哈希,原始代码中有LF_HASH实现,可以复用。需要注意的是,虽然访问rw_trx_hash是线程安全的,但由于已经将其相关操作移出临界区,rw_trx_hash与临界区内的数据对象不再同步,需要在代码实现时保证逻辑正确。

搜索结果
找到“0”个结果

当前产品无相关内容

未找到相关内容,请尝试其他搜索词