暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

论文《TiDB:A Raft-based HTAP Database》阅读感悟(五)

之前总结了TiDB的架构以及TiKVTiFlash的内部细节,本文着重说明TiDB的事务处理能力,事务处理是数据库满足OLTP特性的关键技术。

TiDB的事务隔离级别支持快照隔离(SI可重复读(RRSI允许事务中每个请求读取到数据的一致版本。事务中不同语句对同一个键可能会读取到不同的值(比如RC隔离级别),RR将保证事务中对相同的键将始终读取相同的值。TiDB同时实现了多版本并发控制(MVCC,避免了读写锁定并防止写写冲突。

TiDB中一个事务会涉及到SQL引擎、TiKVPD之间的协同工作,其中:

(1)SQL引擎:负责协调事务。接收客户端SQL请求,将数据转换为KV格式,并使用两阶段提交(2PC)将事务写入TiKV

(2)PD:负责管理逻辑Regions及物理位置;提供全局严格递增的时间戳。

(3)TiKV:提供分布式事务接口,实现MVCC,并将数据持久化到磁盘。

TiDB既实现了乐观锁,也支持悲观锁。锁的实现来自于Percolator模型,该模型选择一个键作为主键,并用它来表示事务的状态,并使用基本的两阶段提交来执行事务。

乐观事务处理流程为:

(1)当收到客户端的begin命令后,SQL引擎向PD请求一个时间戳作为事务的开始时间戳start_ts

(2)SQL引擎从TiKV读取数据并写入本地内存来执行DMLTiKV在事务的start_ts之前提供最近的提交时间戳commit_ts

(3)SQL引擎从客户端接收到commit命令时,它启动2PC协议。它随机选择一个主键,并行锁定所有键,并向TiKV节点发送预写。

(4)如果所有预写成功,SQL引擎向PD请求事务的commit_ts,并向TiKV发送命令。TiKV提交主键并向SQL引擎发送成功响应。

(5)SQL引擎将成功返回给客户端。

(6)SQL引擎通过向TiKV发送进一步的提交命令,以异步和并行的方式提交辅助键并清除锁。

对比悲观锁与乐观锁,其最大的区别在于何时获取锁。乐观事务中,锁是在预写阶段增量获取的;而悲观事务中,锁是在预写之前执行DML时获取。

在悲观事务中锁定键时,SQL引擎获取一个新的时间戳for_update_ts。如果SQL引擎无法获取锁,它可以重试从该锁开始的事务,而不是回滚并重试整个事务。在读取时,TiKV使用for_update_ts而不是start_ts来决定可以读取键的哪些值。通过这种方式悲观事务保持RR隔离级别。悲观事务还允许使用读提交(RC)隔离级别,这样可以减少事务之间的冲突,从而提高性能。

时间戳是由PD分配的,每个时间戳包括物理时间和逻辑时间。物理时间为当前时间,精度为毫秒级别;逻辑时间为18 bit。理论上,PD每毫秒可以分配2^18个时间戳。为降低延迟,客户端按批次从PD申请时间戳。

文章转载自数据源的技术后花园,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论