本文共 2007 字,大约阅读时间需要 6 分钟。
TiKV (字节开源数据库的Key-Value 存储引擎)采用顺序扫(Forward Scan)来读取数据。顺序扫的核心目标是在给定的时间戳范围内,找到所有符合条件的数据版本。这一机制对于确保事务一致性至关重要,特别是在高并发场景下。
以下是顺序扫的实现流程:
在事务写入完成后,RocksDB 中的数据分布如下:
CF 类别 | Key Format | Value Format |
---|---|---|
Lock | Lock 的 Key 和 Timestamp | Lock 的类型、主键、锁持续时间等信息 |
Default | Key + commit_ts | 行键的值 |
Write | Key + commit_ts | beginTransaction的类型和开始时间 |
Key 的编码处理:
顺序扫的代码位于,主要定义为:
def scan(self, scan_ts: Timestamp, lower_bound: Key, upper_bound: Key) -> Result
首次迭代时,将 Lock 和 Write Cursor 同时初始至 lower_bound。
if !self.is_started { if self.cfg.lower_bound.is_some() { self.write_cursor.seek(&self.cfg.lower_bound)?; self.lock_cursor.seek(&self.cfg.lower_bound)?; } else { self.write_cursor.seek_to_first()?; self.lock_cursor.seek_to_first()?; } self.is_started = true;}
Lock Cursor 和 Write Cursor 同时移动,找出第一个遇到的 User Key。
let w_key = if self.write_cursor.valid()? { Some(self.write_cursor.key()) } else { None };let l_key = if self.lock_cursor.valid()? { Some(self.lock_cursor.key()) } else { None };match (w_key, l_key) { // ... Skipping detailed match logic ...}
如果 User Key 来自 Write Cursor:
若没有找到数据,回到步骤 2,若有找到,则根据需要决定是否继续扫描。
以事务 #1 和 #2 为例,结合 RockDB 中的数据,展示了顺序扫如何在给定 scan_ts 下高效读取相关 Key-Value 对。通过样例,清晰地展示了处理锁冲突和版本选择的逻辑,直观地体现了 MVCC 在高并发环境中的优势。
TiKV 的顺序扫机制不仅实现了高效的数据读取,还通过智能 Cursor 调度和版本管理,确保在复杂事务环境下的稳定性和一致性。这一设计为MVCC事务存储提供了坚实的基础,支持大规模实时应用。
转载地址:http://dfkoz.baihongyu.com/