InnoDB MVCC浅谈

                                     作者:周琳//转载请标注出出处

1.行记录隐藏列的意义

可以从row_search_for_mysql(storage/innobase/row/row0sel.cc, line 3661)函数开始,这个函数是mysql服务器层面搜索记录的函数,该函数有一个重要的参数就是row_prebuilt_t*    prebuilt,该参数是包含了查询的记录的信息。进行Debug调试可以发现内存中一行记录包含了如下的几个隐藏列:

测试的客户端:



测试实例中,test1表只有id为int的一列。


    从gdb信息中可以发现,内存中的一行记录有三个隐藏列分别为:DB_ROW_ID、DB_TRX_ID、DB_ROLL_PTR。除过DB_ROW_ID以外,DB_TRX_ID和DB_ROLL_PTR分别代表了每行记录的事务ID和每行记录的回滚指针。InnoDB中有运行期间有一个全局的事务链表,每个事务的开始都会把事务ID放到链表中。DB_ROLL_PTR指针用于指向undo 记录,构造多版本的。

2.InnoDB多版本控制

InnoDB对于每一行记录都维护了2个隐藏列,其中一列存储行辈修改的”时间”,另外一列存储辈删除的”时间”,注意,InnoDB存储的并不是实际的时间哦,而是对应的系统版本号,所以版本号可以作为事务号。对于每一行查询语句,InnoDB都会把这个查询语句的版本号同这个查询语句遇到的行记录的版本号进行比对,然后结合不同的事务隔离界别来选择是否返回该行记录。针对mysql的常见操作进行说明下:

(1)   select操作:

对于select的操作,只有同时满足如下2个条件才返回行记录

a)        行的修改版本号小于等于该事务版本号

b)        行的删除版本号要么没有被定义,要么大于事务版本号。

如果行的修改或者删除版本号大于事务号,说明行是被修改事务后启动的事务修改或者删除的。在可重复读的隔离级别下,后开始的事务堆数据的影响不应该被先开始的事务看见,所以应该忽略后开始的事务的更新或者删除操作。

(2)   insert操作:

新插入的行,行的修改版本号为更新为该事务的事务号。

(3)   update操作:

更新行的时候,InnoDB会把原来行复制一份,并把当前的事务号作为改行的修改版本号。

(4)   delete操作:

对于删除,InnoDB直接把改行的删除版本号修改为当前事务号,相当于标记为删除,而不是物理的删除。真是的删除是在InnoDB的purge线程去做的。

3.MVCC实现原理图

  Innodb启动后会初始化一个全局的事务最系统,事务系统中保存了innodb运行期间事务的所有信息。每当一个线程start或者begin一个事务后,会有一个trx_t的结构作为事务处理的句柄,依据事务ID的大小的不同,去获取read_view_t中对应记录。在read_view_t中有保存了undo的回滚相关信息,MVCC的基本信息依据每个记录的事务ID、回滚指针,去undo链表中查找对应的之前的多版本的数据返回给客户端。这里仅仅是做了个简单的介绍。

				
时间: 2025-01-04 07:52:18

InnoDB MVCC浅谈的相关文章

InnoDB Lock浅谈

数据库使用锁是为了支持更好的并发,提供数据的完整性和一致性.InnoDB是一个支持行锁的存储引擎,锁的类型有:共享锁(S).排他锁(X).意向共享(IS).意向排他(IX).为了提供更好的并发,InnoDB提供了非锁定读:不需要等待访问行上的锁释放,读取行的一个快照.该方法是通过InnoDB的一个特性:MVCC来实现的. 当一个事务获取了行r的共享锁,那么另外一个事务也可以立即获取行r的共享锁,因为读取并未改变行r的数据,这种情况就是锁兼容.但是如果有事务想获得行r的排它锁,则它必须等待事务释放

MYSQL中InnoDB特性浅谈

许久没有更新博客,上周末放假把网易大牛姜sir的著作MYSQL技术内幕InnoDB存储引擎又翻阅了一番,对当前工作的InnoDB特性有了一些新的认识,下面谈谈自己的读后感. 1. InnoDB的体系架构由一系列后台线程,内存池和文件组成,这点与其他DB有相似之处. 在内存中划分了一块区域,即缓冲池,用来临时存放用户读写的数据页. InnoDB上对缓冲池读写数据页,刷新到磁盘等操作也使用了CHECKPOINT机制,LRU算法,这点与SQLSERVER,DB2等数据库设计一致,这里不再阐述.需要注意

浅谈MySQL存储引擎-InnoDB&MyISAM

存储引擎在MySQL的逻辑架构中位于第三层,负责MySQL中的数据的存储和提取.MySQL存储引擎有很多,不同的存储引擎保存数据和索引的方式是不同的.每一种存储引擎都有它的优势和劣势,本文只讨论最常见的InnoDB和MyISAM两种存储引擎进行讨论.本文中关于数据存储形式和索引的可以查看图解MySQL索引 MySQL逻辑架构图: InnoDB存储引擎 InnoDB是默认的事务型存储引擎,也是最重要,使用最广泛的存储引擎.在没有特殊情况下,一般优先使用InnoDB存储引擎. 1??.数据存储形式

浅谈mysql innodb缓存策略

浅谈mysql innodb缓存策略: The InnoDB Buffer Pool Innodb 持有一个存储区域叫做buffer pool是为了在内存中缓存数据和索引,知道innodb bufferpool怎么工作,和利用它读取频繁访问的数据,是mysql优化重要的方面. 理想状况下,把bufferpool的大小调整到足够大,留下足够的内存空间给其他该服务器上的进程(使其无缺页即可).bufferpool越大,innodb 月表现为内存型数据库,从硬盘上一次读取数据,之后并成了从内存中读取数

浅谈数据库并发控制 - 锁和 MVCC

在学习几年编程之后,你会发现所有的问题都没有简单.快捷的解决方案,很多问题都需要权衡和妥协,而本文介绍的就是数据库在并发性能和可串行化之间做的权衡和妥协 - 并发控制机制. 如果数据库中的所有事务都是串行执行的,那么它非常容易成为整个应用的性能瓶颈,虽然说没法水平扩展的节点在最后都会成为瓶颈,但是串行执行事务的数据库会加速这一过程:而并发(Concurrency)使一切事情的发生都有了可能,它能够解决一定的性能问题,但是它会带来更多诡异的错误. 引入了并发事务之后,如果不对事务的执行进行控制就会

MySQL - 两种存储引擎 (MyISAM PK InnoDB) + MVCC

总结 1.两种存储引擎各有各的有点,MyISAM专注性能,InnoDB专注事务.两者最大的区别就是InnoDB支持事务,和行锁. 2.InnoDB采用MVCC(Multi-Version Concurrency Control 多版本并发控制)来支持高并发,一种行级锁的变种.MVCC是通过保存数据在某一个时间点的快照来实现的,也就是说无论事务执行多久,每个事务看到的数据都是一致的.InnoDB的MVCC,是通过在每行记录后面保存两个隐藏的列来实现,这两个列一个保存了行的创建时间,一个保存了行的过

浅谈数据库框架,见笑,请多指正

浅谈数据库框架,见笑,请多指正 http://weibo.com/p/1001603724746155003486 一友说"插件式存储又割裂了SQL引擎的完整逻辑...总体而言在现有框架下MySQL的优化器没有多大改进的价值". 我们且做个技术分析: 1 插件式框架,可以静态/动态加载组件,方便在同类不同属家的模块间切换,这种设计是良好的. 很多软件的设计都采用了"微内核+插件"这样的方式构筑了强大的应用.如Ecplise生态圈. 2 数据库范围内, MySQL的属

浅谈MySQL索引背后的数据结构及算法

摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持 也各不相同,因此MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等.为了避免混乱,本文将只关注于BTree索引,因为这是 平常使用MySQL时主要打交道的索引,至于哈希索引和全文索引本文暂不讨论. 文章主要内容分为四个部分. 第一部分主要从数据结构及算法理论层面讨论MySQL数据库索引的数理基础. 第二部分结合MySQL数据库中

并发浅谈-锁和Token的应用

并发 即在同一时刻内有多个完成同一任务的进程或线程在同时运行.并发一般发生在大流量集中访问如抢购或秒杀等业务场景中,它所带来的影响主要表现在以下两个方面:1:造成系统的负载压力过大.比如说mysql天生在处理大并发时表现的异常吃力,并发大时经常可以造成数据库挂掉.2:造成业务资源的竞争出现.比如说兑换一个激活码,并发下可能会出现两个人同时兑换到的同一个激活码. 从开发的经验来看,一般开发者在写程序逻辑时,绝大多数的情况下是没有考虑并发问题的:这其中有两个方面,一是与业务有关,二是与经验有关:其中