TiKV-分布式事务

分布式事务

会出现一部分修改了,持久化了,一部分没有,破坏了事务的原子性

事务怎样存储到TiKV中

Begin

< 3 , xxx > -> < 3 , Frank >

Commit;

流程:

begin之后,会从PD组件中获取一个时间戳(start_ts)

把修改的数据读取到TiDB Server的内存中,先进行修改,当事务遇到commit的时候,把数据持久化,进入两阶段提交,第一阶段,prewrite,会将在内存中修改的数据给写入到TiKV节点中,将锁信息写入到TiKV节点中,第二阶段:到PD组件中去要一个事务结束时间(commit_ts)。

prewrite:修改数据,TiKV节点会用三个列族来存,第一个对应的是修改的新数据,业务上的id再加上事务开始的时间戳,Default,第二个存储锁信息,在整个分布式事务的模型里面,只给事务的第一行加一把主锁,其他修改的行多依附于主锁,锁加到Lock列族中,W:写锁(主锁)+信息,第三个对应提交信息

commit:第一步到PD获取时间戳(事务真正的结束时间),在Write列族中写入提交信息(id 3 + 110 提交时间戳,100 事务开始时间),向Lock列族中插入一行数据,D:删除锁 (锁的清理),整个事务结束。

其他人想要读id = 3这条数据,先到write列族中id = 3,最近一次修改是什么时候,最近一次是110,100的时候开始的。拿着3和100到Default去找,找到Frank这个值。

如果在write列族中没有找到id = 3最近的提交信息,而在Lock列族中找到一把锁,这个不能读,因为现在正处于其他的会话修改。

分布式事务(继续...)

write不单单只有提交信息,key-value中value的值小于255字节,修改的数据也放到里面。

分布式事务(继续...)

修改两行数据,如果两条数据在不同的TiKV下,会造成一个成功了,另一个可能失败了。

解决:

pk:主锁

所以(1,Jack)那行是主锁

而(1,Candy)是@1,我不是主锁,我的主锁在1这,存的是锁的指向

Commit:

获取时间戳

写提交信息

清理锁信息

TiKV Node 1已经写了提交信息,数据就持久化了。但是TiKV Node 2修改还没有持久化,这个时候宕掉了,再启时,数据就没有了。

读id 为 2的时候,在write里面没有信息,到Lock里面读到一把锁,发现锁指向id = 1,看到主锁被删掉了,可能在修改时出现问题了,就补上Write和Lock

MVCC

-Transaction 1:

Begin(start_ts = 100)

<1,Tom> -> <1,Jack >

<2,Andy> -> <2,Candy>

Commit;(commit_ts = 110)

-Transaction 2:

Begin (start_ts = 115)

<1,Jack> -> <1,Tim>

<4,Tony> -> <4,Jerry>

如果我修改几万行信息,我在做修改的时候,就不能对它们读写了,效率低。

多版本并发控制:让它读,id = 1,Jack改Tim,现在还不确定改不改,就可以读。

原来版本(看Transaction 1),在修改的时候不修改当前的数据,新生成一个副本,有两个副本,一个副本是未提交的,把Jack可以随便改,我读的是原来的(未提交的)。给两个副本一个时间戳,就可以了。

在TSO =120 的时候读取key =1 /2 /4

没有MVCC,只能读2

有MVCC后,1应该读出Jack,4为Tony,2是Candy

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值