TiKV的MVCC和分布式事务流程

基础的事务流程(数据不在多个tikv

事务的存储流程。

Begin

<3,xxx>——<3,frank>

Commit;

1.新begin,然后从pd中获得时间戳TSO,也就是start_ts

2.把修改的数据读取出来,读到tidb server的内存中,内存中先修改,

3.commit进行两阶段提交

一阶段:prewrite:内存中修改的数据写入到tikv节点中,然后将锁信息写入到tikv中。

:key+tso+value(3_100,frank)写信息存到default的cf中,update和delete只放新值。给修改的第一行的key加个主锁,锁信息放到lock的cf中   <3,(W,pk,3,100……)>    3是key,W是写锁 ,pk表示主锁,key,100是事务开始时间start_ts,后面的不加锁,依附于第一行。

二阶段:commit:pd组件中要时间TSO(commit_ts),还会写个提交信息

:pd获取时间commit_ts,在write的cf中写入信息<3_110,100> key+start_ts+commit_ts。再做个锁清理,在lock的cf中插入3,(D,pk,3,100……)  D表示锁被删了。

tikv中有3类cf

Default   修改的数据

Lock       锁信息

Write      提交信息

在commit之前,begin之后,锁信息别人感知的到吗

锁信息在内存中,不写到tikv节点中,别人感知不到锁,就是乐观事务

锁信息提前从内存中写入tikv节点,别人也能在commit前感知到锁,就是悲观事务

先到write的cf中看,最近一次修改时间,拿着key+start_ts到default的cf中找到value。

如果在writecf中没看到值,但是lockcf中有,那就不能读(有误,待改正)

如果数据小于255字节,会直接存储到writecf中,大于255字节就是正常写到defaultcf或者自己指定的cf

分布式事务流程(数据多个tikv

Begin

<1,tom>——<1,jack>

<2,andy>——<2,candy>

Commit;

1.只写新值进去。<1,tom>——<1,jack>只写<1,jack>

2.只有第一行需要加主锁,后面的都是指向锁。

3.updatedelete只放新值(putdel

两行数据放在不同的tikv node上。

1.新begin,然后从pd中获得时间戳TSO,也就是start_ts

2.把修改的数据读取出来,读到tidb server的内存中,内存中先修改,

3.commit进行两阶段提交

一阶段:prewrite(预写):内存中修改的数据写入到tikv节点中,然后将锁信息写入到tikv中。

第一行<1,jack>(放在tikv node1中):

key+tso+value(1_100,jack)写信息存到default的cf中,update和delete只放新值。给修改的第一行的key加个主锁,锁信息放到lock的cf中   <1,(W,pk,1,100……)>,1是key,W是写锁 ,pk表示主锁,key,100是事务开始时间start_ts,后面的不加锁,依附于第一行。

第二行<2,candy>(放在tikv node2中):

key+tso+value(2_100,candy)写信息存到default的cf中,update和delete只放新值。给修改的第二行的key加个锁指向,锁信息放到lock的cf中   <2,(W,@1,2,100……)> ,2是key,W是写锁 ,@1表示锁的指向,指向key1,2表示key,100是事务开始时间start_ts,后面的不加锁,依附于第一行。

二阶段:commit(提交):pd组件中要时间TSO(commit_ts),还会写个提交信息

第一行:

pd获取时间commit_ts,在write的cf中写入信息<1_110,100> key+start_ts+commit_ts。再做个锁清理,在lock的cf中插入1,(D,pk,1,100……)  D表示锁被删了。

第二行:

write的cf中写入信息<2_110,100> key+start_ts+commit_ts。再做个锁清理,在lock的cf中插入2,(D,@1,2,100……)  D表示锁被删了。

Tso 120时间 

看tikv node1的write的cf,看结束时间离120最近的是110,然后开始时间是100,再到default里找value。

2节点一样。

原子性:

如果tikv node1提交了,tikv node2没提交,并且tikv node2宕了。

读取,发现tikv node2的write的cf中没数据,发现lock中有个指向1的锁,然后去node1的lock的cf发现锁已经被删了。在node2的write中补上<2,110_100>,在lock中补上<2,(D,@1,2,100……)>

简单来说:宕了起来后,default中的key和value(数据还在)还在,从1中找到锁的记录,回到2补全commit的二阶段。

MVCC(多版本并发控制)

TSO120的时候

读取key=1,2,4

1  jack

2  candy

4  tony

事务1完成,事务2未提交,所以读在write里读到的就是上面的值。

假设全部是悲观事务。即使没commit,别人也能感觉到锁。可见图中lock的cf。

假设当前TSO=120

Key=1

想读

在write的cf中读 key(1)离当前时间(120)最近的commit_ts110的行,获取到了start_ts(100),拿着开始时间(100)和key(1)去default的cf找value(jack),成功获取值。

想写

在write的cf中读key(1)离当前时间(120)最近的commit_ts110的行,获取到了start_ts(100),

拿着开始时间(100)和key(1)去lock的cf找到锁<1,(W,pk,1,115,…..)> ,发现lock中的start_ts(115)大于write的cf中的put<1_110,100>的100,所以有锁且没提交,不能写,造成堵塞。

Key=2

想读

在write的cf中读 key(2)离当前时间(120)最近的commit_ts110的行,获取到了start_ts(100),拿着开始时间(100)和key(2)去default的cf找value(candy),成功获取值。

想写

在write的cf中读key(2)离当前时间(120)最近的commit_ts110的行,获取到了start_ts(100),拿着开始时间(100)和key(2)去lock的cf找锁,没发现锁,能写,不造成堵塞。

Key=4

想读

在write的cf中读 key(4)离当前时间(120)最近的commit_ts90的行,获取到了start_ts(80),拿着开始时间(80)和key(4)去default的cf找value(tony),成功获取值。

想写

在write的cf中读key(4)离当前时间(120)最近的commit_ts90的行,获取到了start_ts(80),拿着开始时间(80)和key(4)去lock的cf找到锁<4,(W,@1,115,…..)> ,根据@1去找到key=1的锁,发现有锁存在,所以有锁且没提交,不能写,造成堵塞。

  • 14
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

汪灵骅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值