首页
随机
最近更改
特殊页面
社群首页
参数设置
关于WHY42
免责声明
WHY42
搜索
用户菜单
登录
欢迎来到Riguz的小站!这是一个私人wiki,用来记录一些我的笔记。
查看“︁MVCC”︁的源代码
←
MVCC
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
=MVCC简述= Multi-Version Concurrency Control 多版本并发控制 在并发读写数据库时,读操作可能会不一致的数据(脏读)。为了避免这种情况,需要实现数据库的并发访问控制,最简单的方式就是加锁访问。由于,加锁会将读写操作串行化,所以不会出现不一致的状态。但是,读操作会被写操作阻塞,大幅降低读性能。在Java concurrent包中,有<span class="article-label">copyonwrite</span>系列的类,专门用于优化读远大于写的情况。而其优化的手段就是,在进行写操作时,将数据copy一份,不会影响原有数据,然后进行修改,修改完成后原子替换掉旧的数据,而读操作只会读取原有数据。通过这种方式实现写操作不会阻塞读操作,从而优化读效率。而写操作之间是要互斥的,并且每次写操作都会有一次copy,所以只适合读大于写的情况。 MVCC的原理与copyonwrite类似,全称是Multi-Version Concurrent Control,即多版本并发控制。在MVCC协议下,每个读操作会看到一个一致性的snapshot,并且可以实现非阻塞的读。MVCC允许数据具有多个版本,这个版本可以是时间戳或者是全局递增的事务ID,在同一个时间点,不同的事务看到的数据是不同的。 =MySQL MVCC= mysql的innodb采用的是行锁,而且采用了多版本并发控制来提高读操作的性能。在每一行记录的后面增加两个隐藏列,记录创建版本号和删除版本号,而每一个事务在启动的时候,都有一个唯一的递增的版本号。 ==插入== 在插入操作时 : 记录的创建版本号就是事务版本号。 比如我插入一条记录, 事务id 假设是1 ,那么记录如下:也就是说,创建版本号就是事务版本号。 {| class="wikitable" border="1" |- | id | name | create version | delete version |- | 1 | test | 1 | |} ==更新== 在更新操作的时候,采用的是先标记旧的那行记录为已删除,并且删除版本号是事务版本号,然后插入一行新的记录的方式。 比如,针对上面那行记录,事务Id为2 要把name字段更新 <source lang="sql"> update table set name= 'new_value' where id=1; </source> {| class="wikitable" border="1" |- | id | name | create version | delete version |- | 1 | test | 2 | 2 |- | 1 | xxxx | 2 | |} ==删除== 删除操作的时候,就把事务版本号作为删除版本号。比如 <source lang="sql"> delete from table where id=1; </source> {| class="wikitable" border="1" |- | id | name | create version | delete version |- | 1 | xxxx | 2 | 3 |} [[Category:MySQL]] [[Category:Database]]
返回
MVCC
。