MVCC:修订间差异

来自WHY42
imported>Soleverlee
以“=MVCC简述= Multi-Version Concurrency Control 多版本并发控制 在并发读写数据库时,读操作可能会不一致的数据(脏读)。为了避免...”为内容创建页面
 
Riguz留言 | 贡献
 
(未显示2个用户的3个中间版本)
第2行: 第2行:
Multi-Version Concurrency Control 多版本并发控制
Multi-Version Concurrency Control 多版本并发控制


在并发读写数据库时,读操作可能会不一致的数据(脏读)。为了避免这种情况,需要实现数据库的并发访问控制,最简单的方式就是加锁访问。由于,加锁会将读写操作串行化,所以不会出现不一致的状态。但是,读操作会被写操作阻塞,大幅降低读性能。在Java concurrent包中,有copyonwrite系列的类,专门用于优化读远大于写的情况。而其优化的手段就是,在进行写操作时,将数据copy一份,不会影响原有数据,然后进行修改,修改完成后原子替换掉旧的数据,而读操作只会读取原有数据。通过这种方式实现写操作不会阻塞读操作,从而优化读效率。而写操作之间是要互斥的,并且每次写操作都会有一次copy,所以只适合读大于写的情况。
在并发读写数据库时,读操作可能会不一致的数据(脏读)。为了避免这种情况,需要实现数据库的并发访问控制,最简单的方式就是加锁访问。由于,加锁会将读写操作串行化,所以不会出现不一致的状态。但是,读操作会被写操作阻塞,大幅降低读性能。在Java concurrent包中,有<span class="article-label">copyonwrite</span>系列的类,专门用于优化读远大于写的情况。而其优化的手段就是,在进行写操作时,将数据copy一份,不会影响原有数据,然后进行修改,修改完成后原子替换掉旧的数据,而读操作只会读取原有数据。通过这种方式实现写操作不会阻塞读操作,从而优化读效率。而写操作之间是要互斥的,并且每次写操作都会有一次copy,所以只适合读大于写的情况。


MVCC的原理与copyonwrite类似,全称是Multi-Version Concurrent Control,即多版本并发控制。在MVCC协议下,每个读操作会看到一个一致性的snapshot,并且可以实现非阻塞的读。MVCC允许数据具有多个版本,这个版本可以是时间戳或者是全局递增的事务ID,在同一个时间点,不同的事务看到的数据是不同的。
MVCC的原理与copyonwrite类似,全称是Multi-Version Concurrent Control,即多版本并发控制。在MVCC协议下,每个读操作会看到一个一致性的snapshot,并且可以实现非阻塞的读。MVCC允许数据具有多个版本,这个版本可以是时间戳或者是全局递增的事务ID,在同一个时间点,不同的事务看到的数据是不同的。
=MySQL MVCC=
=MySQL MVCC=
mysql的innodb采用的是行锁,而且采用了多版本并发控制来提高读操作的性能。在每一行记录的后面增加两个隐藏列,记录创建版本号和删除版本号,而每一个事务在启动的时候,都有一个唯一的递增的版本号。
mysql的innodb采用的是行锁,而且采用了多版本并发控制来提高读操作的性能。在每一行记录的后面增加两个隐藏列,记录创建版本号和删除版本号,而每一个事务在启动的时候,都有一个唯一的递增的版本号。
1、在插入操作时 : 记录的创建版本号就是事务版本号。  
==插入==
在插入操作时 : 记录的创建版本号就是事务版本号。  


比如我插入一条记录, 事务id 假设是1 ,那么记录如下:也就是说,创建版本号就是事务版本号。
比如我插入一条记录, 事务id 假设是1 ,那么记录如下:也就是说,创建版本号就是事务版本号。
 
{| class="wikitable" border="1"
id   name   create version   delete version  
|-
1 test   1
| id
2、在更新操作的时候,采用的是先标记旧的那行记录为已删除,并且删除版本号是事务版本号,然后插入一行新的记录的方式。
| name
| create version
| delete version
|-
| 1
| test
| 1
|
|}
==更新==
在更新操作的时候,采用的是先标记旧的那行记录为已删除,并且删除版本号是事务版本号,然后插入一行新的记录的方式。


比如,针对上面那行记录,事务Id为2 要把name字段更新
比如,针对上面那行记录,事务Id为2 要把name字段更新
 
<source lang="sql">
update table set name= 'new_value' where id=1;
update table set name= 'new_value' where id=1;
 
</source>
id     name   create version   delete version  
{| class="wikitable" border="1"
1   test   1 2        
|-
1   new_value   2
| id
| name
 
| create version
3、删除操作的时候,就把事务版本号作为删除版本号。比如
| delete version
 
|-
| 1
| test
| 2
| 2
|-
| 1
| xxxx
| 2
|
|}
==删除==
删除操作的时候,就把事务版本号作为删除版本号。比如
<source lang="sql">
delete from table where id=1;  
delete from table where id=1;  
 
</source>
{| class="wikitable" border="1"
|-
| id
| name
| create version
| delete version
|-
| 1
| xxxx
| 2
| 3
|}
   
   
 
[[Category:MySQL]]
id   name   create version   delete version  
[[Category:Database]]
1 new_value 2 3  
 
[[Category:Algorithm]]

2023年12月19日 (二) 09:14的最新版本

MVCC简述

Multi-Version Concurrency Control 多版本并发控制

在并发读写数据库时,读操作可能会不一致的数据(脏读)。为了避免这种情况,需要实现数据库的并发访问控制,最简单的方式就是加锁访问。由于,加锁会将读写操作串行化,所以不会出现不一致的状态。但是,读操作会被写操作阻塞,大幅降低读性能。在Java concurrent包中,有系列的类,专门用于优化读远大于写的情况。而其优化的手段就是,在进行写操作时,将数据copy一份,不会影响原有数据,然后进行修改,修改完成后原子替换掉旧的数据,而读操作只会读取原有数据。通过这种方式实现写操作不会阻塞读操作,从而优化读效率。而写操作之间是要互斥的,并且每次写操作都会有一次copy,所以只适合读大于写的情况。

MVCC的原理与copyonwrite类似,全称是Multi-Version Concurrent Control,即多版本并发控制。在MVCC协议下,每个读操作会看到一个一致性的snapshot,并且可以实现非阻塞的读。MVCC允许数据具有多个版本,这个版本可以是时间戳或者是全局递增的事务ID,在同一个时间点,不同的事务看到的数据是不同的。

MySQL MVCC

mysql的innodb采用的是行锁,而且采用了多版本并发控制来提高读操作的性能。在每一行记录的后面增加两个隐藏列,记录创建版本号和删除版本号,而每一个事务在启动的时候,都有一个唯一的递增的版本号。

插入

在插入操作时 : 记录的创建版本号就是事务版本号。

比如我插入一条记录, 事务id 假设是1 ,那么记录如下:也就是说,创建版本号就是事务版本号。

id name create version delete version
1 test 1

更新

在更新操作的时候,采用的是先标记旧的那行记录为已删除,并且删除版本号是事务版本号,然后插入一行新的记录的方式。

比如,针对上面那行记录,事务Id为2 要把name字段更新

update table set name= 'new_value' where id=1;
id name create version delete version
1 test 2 2
1 xxxx 2

删除

删除操作的时候,就把事务版本号作为删除版本号。比如

delete from table where id=1;
id name create version delete version
1 xxxx 2 3