TiDB-从0到1-分布式事务

在这里插入图片描述
TiDB从0到1系列

一、事务定义

这属于老生常谈了,无论不管是传统事务还是分布式事务都离不开ACID

  • A:原子性
  • C:一致性
  • I:隔离性
  • D:持久性

二、隔离级别

同样都是老一套东西,主要应对脏读、幻读、不可重复读等问题

  • 读未提交
  • 读已提交
  • 可重复读
  • 可串行化

在TiDB中,实现了快照隔离 (Snapshot Isolation, SI) 级别的一致性:
事务只能看到早于它开始时刻之前提交的其他事务。
在这里插入图片描述
如图,T2是无法访问到T1事务的内容,T3是可以访问T1、T2事务中的内容。

而快照隔离基本是基于Percolator事务模型原理实现的

Percolator 模型

Percolator模型是Google在2010年提出的一种分布式事务处理模型,其设计目标是在大规模分布式系统中实现高效的事务处理。Percolator是一种乐观的事务模型,写写冲突被延迟到事务提交时才会进行检测。可见性与冲突检测依赖于事务的开始时间戳以及提交时间戳。
Percolator模型是一个典型的通过两阶段提交(2PC)进行分布式事务协调的实现。事务的实现主要依靠三个参与者:Percolator客户端、BigTable TabletServer、Timestamp Oracle(TSO)。按照2PC的要求分为两个步骤:PreWrite和Commit。
Percolator模型中,事务执行的过程可以概括为以下几个步骤:

  • Percolator客户端作为事务协调者,负责发起事务请求。 BigTable TabletServer接收并处理事务请求。
  • Timestamp Oracle(TSO)提供时间戳服务,确保事务的顺序性和一致性。
  • 在PreWrite阶段,TSO分配一个时间戳给事务,BigTable TabletServer将事务的写请求记录在本地。
  • 在Commit阶段,TSO根据事务的时间戳和BigTable TabletServer的记录,决定是否提交事务。
  • Percolator模型的一个创新点在于,它依靠对时间戳的使用和BigTable的单行事务,实现了跨行事务。由于某一行数据可以位于不同的BigTable的TabletServer之上,所以该事务也是跨节点的。

这里也再次印证TiDB中为什么事务在开始前和提交时会分别获取一次TSO。

三、TiDB-分布式事务(单行)

1、Begin(开启一个事务)

此时会从PD获取一个TSO,假设为100

2、SQL

update test set name=‘Frank’ where id=3;

3、Commit(提交事务)

此时再次从PD获取一个TSO,假设为110

4、进入2PC阶段
  • prewrite阶段
    在这里插入图片描述
    将数据:3(id)_100(事务开始的TSO),Frank(数据内容)记录在默认链表中
    将锁信息:3(id),W(写锁),pk(主锁),3(id),100(事务开始的TSO),Frank(数据内容)记录在锁链表中
  • commit阶段
    在这里插入图片描述
    将锁信息:3(id),D(已释放的锁),pk(主锁),3(id),100(事务开始的TSO),Frank(数据内容)记录在锁链表中
    将数据:3(id)_110(事务提交的TSO),100(事务开始的TSO)记录在更新链表中

这里有两个细节
1、TiDB中的DML都是以追加的方式实现。
做一个对比
传统关系型数据库:

begin;insert into test(id,name) values(1,'zmz');commit;
begin;update test set name='MySQL' where id=1;commit;
begin:update test set name='TiDB' where id=1;commit;

此时底层其实只有一条数据,就是id:1\name:TiDB

TiDB数据库:

begin;insert into test(id,name) values(1,'zmz');commit;
begin;update test set name='MySQL' where id=1;commit;
begin:update test set name='TiDB' where id=1;commit;

此时底层其实是有三条数据的

id:1\name:TiDB
id:1\name:MySQL
id:1\name:zmz

那么当我们在TiDB查询test表时会查到3条数据吗?当然不会,而是根据提交事务的TSO读取到最新的数据。
那么长期看来是不是会有非常多的冗余无效数据呢?当然也不会,GC模块会定时清理掉历史版本数据。

2、上面提到主锁机制
TiDB的分布式事务中,假设一条事务涉及多行数据,那么将采用主锁机制:只对事务的第一行数据上锁,后面的数据跟随第一行的主锁。

四、TiDB-分布式事务(多行)

1、Begin(开启一个事务)

此时会从PD获取一个TSO,假设为100

2、SQL

update test set name=‘Jack’ where id=1;
update test set name=‘Candy’ where id=2;

3、Commit(提交事务)

此时再次从PD获取一个TSO,假设为110

4、进入2PC阶段
  • prewrite阶段
    在这里插入图片描述
    这里与单行数据事务最大的不同是,第二行数据的加锁信息:
    2(id),W(写锁),@1(跟随主锁1),2(id),100(事务开始的TSO),Candy(数据内容)

  • commit阶段
    在这里插入图片描述
    主锁释放后,跟随锁一起释放。
    再次强调,这里的释放不是删除,而是插入新的锁清理记录。

彩蛋

TiDB可以动态调整事务的隔离级别和锁的实现方式

  • 根据transaction_isoiation设置隔离级别
  • 根据tidb_txn_mode设置乐观锁还是悲观锁

在这里插入图片描述

  • 22
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值