MVCC 、CAS 和CopyOnWrite

来源:互联网 发布:windows未能启动成功 编辑:程序博客网 时间:2024/04/26 07:52

update一行的时候的时候不是in-place的修改,而是产生一个行的新版本,在新行上修改,最后有点类似copy on write array,在提交的时候切换到新版本。好处是不影响现有数据的读取,一致性好。

概括为:准备数据 + 原子commit 切换版本,和无锁数据结构实现的思路很像,先准备好数据,最后往结构上挂的那一下用CAS原子性保证。MVCC是把一个复杂事务的原子性问题转化到commit动作的原子性上来。

CAS 是一种思想:Conditional Update,后验保证一致,而锁是前验机制。CAS的基本框架

1)读取当前状态 

2)基于读取的状态进行计算得到新状态。

3)Conditional Update:如果计算结果基于的状态没有变,则更新,否则回到第一步。


system model:

Server State A  —— Transaction  T——> Server State B

和一个版本管理系统比如TFS类比:changeset 就是 transaction, changeset number就是 transaction id

每个文件有版本,整个代码库也有版本,都是以changeset number做为版本号。整个代码库的版本历史就是所有的changeset number,是连续的,而文件的版本历史是非连续的,因为不是每个changeset都修改这个文件。


数据库

每个事务分配一个Transaction Id,是自增的。server的当前版本就是上一次成功提交的transaction Id

INNoDB实现MVCC的方法,每一行有2个隐藏字段,记录创建本行的事务ID和删除本行的事务ID(如果被删了的话)

在一个事务中:

对于insert,把当前事务ID填到新行的Create字段

对于delete,把当前事务ID填到要删除的行的Delete字段

对于update,产生一个新行,把旧行标记删除

对于select,返回的记录满足两个条件

1) 行的create事务ID 小于等于Server 当前版本号,(或者等于当前事务ID,本次事务创建的行)这确保读到的数据都是已经提交的

2)行的delete事务ID 大于当前事务ID ,当前事务之后的事务才删除的数据在当前事务可以被读到。

具体的,每个事务会拷贝一个“当前活动事务列表“,用其中最小的那个做为select的上界。相当于在事务开始的时候保存了server的版本号,之后就算有别的事务提交increment了server的版本,当前事务一直用自己保存的那个,Repeatable read。


事务提交就是更新server的当前版本为当前commit的事务号。

标记删除的数据用一个后台janitor定期处理,这个叫purge。



1

0 0