【内存多版本实现方案概述】
在当前的TNT系统中,由于事务处理涉及多次内外存日志同步,导致事务性能受到影响。为了解决这一问题,本文提出了一个内存多版本的实现方案,旨在优化事务处理效率,减少对外存的依赖,提高系统性能。
【虚拟Rowid机制】
针对TNT无法直接获取Rowid的问题,我们引入了虚拟Rowid的概念。在数据尚未写入外存时,系统为每条数据分配一个唯一的虚拟Rowid作为标识。这样,在数据被持久化到外存之前,所有的操作(如插入、更新、删除和回滚)都在内存中进行,仅在purge过程中,数据才被刷到外存,并获得真实的Rowid。
【Purge操作】
Purge过程分为两个步骤:第一步,将内存中的数据物化到外存;第二步,从内存中删除这些数据。为了保持真实Rowid与虚拟Rowid之间的映射,我们使用双向Hash表。在purge的第一阶段建立映射,第二阶段完成后删除,确保在内存中无冗余数据。
【数据更新处理】
在purge过程中,如果发现被更新的数据使用虚拟Rowid标识,系统会检查双向Hash表中是否存在对应的真实Rowid。如果存在,更新记录的虚拟Rowid为真实Rowid。
【数据扫描策略】
数据扫描分为表扫描和索引扫描:
1. **表扫描**:
- 外存和内存数据都需要读取。
- 先读取外存数据,查找内存中的新版本。如果内存中的新版本用虚拟Rowid标识,选择外存数据,将虚拟Rowid加入过滤Hash。否则,选择内存数据。
- 读取内存数据时,使用虚拟Rowid过滤Hash避免重复读取。
2. **索引扫描**:
- 同样需要读取内外存数据。
- 由于虚拟Rowid和真实Rowid长度可能不同,内外存索引顺序可能不一致,可能导致重复读或漏读。
- 扫描过程中,内外存索引同步进行。当遇到虚拟Rowid时,检查是否已存在于过滤Hash中,防止重复读。
【防重复读策略】
在索引扫描中,如果读到内存项是虚拟Rowid且尚未被purge,可能会遇到重复读问题。例如,读到key=a, vrid=2后,它被purge到外存,对应的真实Rowid为arrid=6。为解决这个问题,采取以下策略:
- 如果选择的内存项是虚拟Rowid,检查其是否在双向Hash中。如果存在,跳过;如果不存在,则返回,并将其添加到虚拟Rowid过滤Hash中。
此内存多版本实现方案旨在简化事务处理流程,提高系统效率,通过虚拟Rowid和精心设计的purge及数据扫描机制,实现内存中的多版本控制,同时减少了对外存的依赖,降低了系统复杂性。