MVCC 、CAS 和CopyOnWrite
2015-12-17 16:55
253 查看
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
概括为:准备数据 + 原子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
相关文章推荐
- linux下如何处理文件名含括号的文件
- log4j.properties配置文件配置项的说明
- 性能测试分享:jmeter性能监控(一)
- nginx缓存映射在内存中的结点的生命周期
- 合成存取方法 @property @synthesize
- 系统日志相关操作总结
- 性能测试分享:Jmeter的api监控工具解决方案
- 《Linux 工作站安全检查清单》——来自 Linux 基金会内部
- opengl纹理贴图(续)
- nginx如何读取缓存文件
- 在linux上创建nfs遇到的问题。
- 开发必会的 Linux & Mac 命令
- nginx如何响应客户端
- Linux指令--mv
- Linux指令--mv
- win10系统Powershell重置应用失效的解决办法
- php+nginx+mysql+ubuntu环境搭建
- Hadoop Combiner类 简单测试
- linux下Nginx+tomcat整合的安装与配置
- Linux下的Mysql笔记整理(二)