Mysql-MVCC - Go语言中文社区

Mysql-MVCC



Mysql InnoDB存储引擎基于Multi-Version Concurrency Control(MVCC,多版本的并发控制协议)实现。MVCC是通过保存数据在某个时间点的快照来实现的优点是:读不加锁,读写不冲突。

 

 原理

1 实现原理

InnoDB的MVCC可以是通过在每行记录中保存两个隐藏的列来实现的,创建事物id,删除事物id。开始一个新的事务,系统版本号(可以理解为事务的ID)就会自动递增,事务开始时刻的系统版本号会作为事务的ID。

Innodb最基本行记录(row中包含一些额外的存储信息:DATA_TRX_ID,DATA_ROLL_PTR,DB_ROW_ID,DELETE BIT

列名

长度

备注

DATA_TRX_ID

6字节

标记了最新更新这条行记录的transaction id,每处理一个事务,事物值自动+1

DATA_ROLL_PTR

7字节

指向当前记录项的rollback segment的undo log记录,找之前版本的数据就是通过这个指针

DB_ROW_ID

6字节

innodb自动产生聚集索引时,聚集索引包括这一列,否则聚集索引中不包括这个值。

DELETE BIT

 

位用于标识该记录是否被删除,这里的不是真正的删除数据,而是标志出来的删除。真正意义的删除是在commit的时候

 

2 Select

当隔离级别是REPEATABLE READ时select操作,InnoDB查询时必须保证每行数据符合两个条件:

InnoDB只查找版本号必须小于等于事务版本的数据行。这确保当前事务读取的行都是事务之前已经存在的,或者是由当前事务创建或修改的行。

行的删除操作的版本一定是未定义的或者大于当前事务的版本号,确定了当前事务开始之前,行没有被删除。

 

3 实现

MVCC有下面几个特点(看起来有点乐观锁的味道):

a、每行数据都存在一个版本。

b、每次数据更新时都更新该版本 修改时Copy出当前版本随意修改,个事务之间无干扰。

c、保存时比较版本号,如果成功(commit),则覆盖原记录;失败则放弃copy(rollback)。

 

Innodb的MVCC实现方式如下:

a、事务以排他锁的形式修改原始数据,

b、把修改前的数据存放于undo log,通过回滚指针与主数据关联

c、修改成功(commit)啥都不做,失败则恢复undo log中的数据(rollback)

 

 MVCC示例

接下来讲述在REPEATABLE READ隔离级别下,MVCC具体是如何操作的

 

1 表结构

假设存在表user,结构如下:

2cd46eb48ead102977e55d7a4a04c45bc8dad678

加上DATA_TRX_ID、DATA_ROLL_PTR、DB_ROW_ID后的结果如下:

2e9c10b88906835f32b89dd14c54586805c95314

 

2 insert

假设当前事务id=1,插入一条记录,sql如下:

insert into user value("a1")

结果数据如下:

653ec2d114308c83c33f2e4c9eea5410a64958d5

 

3 update

假设原始数据如下:

937b9979277abc370c7ecd63ca26c22ee6953382

假设当前事务id=2,更新sql如下:

update user set name="a2" where id =1;

更新时数据变动如下:

c8c8ea9cd1070c9c7737aa4e29b9fa231267bfd1

事务执行过程:

事务开始.

记录name=a1 到undo log.

修改name=a2、DATA_ROOL_PTR=UNDO LOG的记录id

记录name=a2 到redo log.

将redo log、undo写入磁盘。

事务提交

说明:如果undo log一直不删除,则会通过当前记录的回滚指针回溯到该行创建时的初始内容,所幸的时在Innodb中存在purge线程,它会查询那些比现在最老的活动事务还早的undo log,并删除它们,从而保证undo log文件不至于无限增长。

 

4  delete

假设原始数据如下:

719f9241cc76c903b6156f17169613cbd8b0ed2f

 

假设当前事务id=3,delete sql如下:

delete from user where id =1

50d23ac986b7e0d3e9839536566888bcfc002b39

事务执行过程:

事务开始.

记录原数据到undo log.

修改记录的DELETE BIT=1、DATA_ROOL_PTR=UNDO LOG的记录id

记录删除操作到redo log.

将redo log、undo写入磁盘。

事务提交

 

 

 

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_33725239/article/details/89613836
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-03-07 20:39:32
  • 阅读 ( 1399 )
  • 分类:数据库

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢