CSE_lecture13:Transaction and Multi-site Transaction
Transaction & Multi-site Transaction
transaction with high-performance
在读多写少的情况下,即大部分事务只读,且单个事务中读远多于写,OCC和2PL能实现很快的性能,但原生的OCC和2PL还不行
对于OCC来说,如果中途有数据被修改了,读修改前的状态就好了。因此引入versionedData,即snapshot
1 | |
在事务读之前维护一个时钟,即所有读只读某一个版本的数据,而写的时候需要引入新版本(这个版本应当约等于事务提交时间),可以使用global counter来FAA(fetch and add)时间戳,事务开始和提交时都需要FAA
对OCC的改进方法为,事务开始时获取开始时钟,从而确定read时的snapshot,而write还是要缓存在write set中;提交时获取提交时钟,write时的version为该时钟,并保留以前的snapshot;现在不需要再validate了
但snapshot可能出现写到一半就被别人FAA的问题,因此需要保证整个写都原子化
1 | |
注意要先拿锁,再commit FAA,否则还是会读到原来的snapshot
此时write还是可能出现漏加的情况,因此写操作不能从同一个snapshot来修改,因此还是需要validate
多版本并发控制(MVCC)的流程如下,即validate检查在start time后是否出现了新的snapshot:
MVCC实际上并没有保证before-or-after,由于validate阶段没有检查read,会出现写偏斜(write skew)
为了保证conflict serializability,可以在read-write事务中检查read set,虽然会退化到OCC,但实际用的不少(因为读远多于写,而只读事务不用检查read set);或者不考虑(snapshot isolation, SI)
multi-site transaction & multi-site atomicity
用于处理事务的partial failure,出现场景为跨机器访问数据(数据切块),此时希望全提交或全放弃
因此需要一个中心化的事务决定是否提交,即high-layer TX,具体操作单台机器的操作为low-layer TX,所有的low-layer TX要么全提交,要么都放弃
此时需要two-phase commit:
- preparation/voting: low-layer TX只能tentatively commit/abort,high-layer TX评估lower的情况
- commitment: hight-layer决定low-layer是提交还是放弃
2PC会导致通信量增加,此时会出现unreliable communication,此时需要coordinator将abort/commit的决定写入log,worker在收到coordinator的消息前都应该等待
prepare failure有以下情况:
- prepare消息丢失:超时就重发
- prepare的ACK丢失:同上
- prepare阶段worker挂了:让其他worker放弃
- coordinator挂了:log中还没有决定,直接全放弃
此时worker在恢复后,不能自己决定是否提交,而是询问coordinator,由coordinator决定
commit failure有以下情况:
- commit消息丢失:超时就重发
- commit的ACK丢失:同上
- commit阶段worker挂了:恢复后向coordinator询问是否提交
- coordinator挂了:根据log重做所有的提交,可能出现某些worker多次收到提交,第二次收到时由于已经提交,直接返回就好
low-layer TX需要等到coordinator决定提交后才放2PL锁,而coordinator已经帮OCC做了validate & commit阶段;lower-layer TX的log需要标记为partial-checkpoint,此时还不能清理