mysql innodb mvcc

栏目: 数据库 · 发布时间: 5年前

内容简介:自我理解: MVCC可以允许非阻塞式读, 在锁操作时只锁定必要的记录。锁保证更新的并发性,MVCC主要保证读的并发性和锁时只锁必要的记录。 线程该不该看到别的线程操作的东西因为innodb为了读的并发性使用的是非锁定读,所以在读的时候使用MVCC来保证事务更新的隔离性

自我理解: MVCC可以允许非阻塞式读, 在锁操作时只锁定必要的记录。

锁保证更新的并发性,MVCC主要保证读的并发性和锁时只锁必要的记录。 线程该不该看到别的线程操作的东西

因为innodb为了读的并发性使用的是非锁定读,所以在读的时候使用MVCC来保证事务更新的隔离性

目录

1.InnoDB MVCC 简介

2.InnoDB 实现MVCC的方式

3.InnoDB行记录格式

4.Read View与可见性

4.1 事务链表

4.2 Read View结构

4.3 可见性判断

5.Undo log格式

5.1 insert undo log有什么用?

5.2 为什么insert undo log对其他事务不可见?

5.3 那第一条记录插入后的读取的都是当前行?

6.各写操作下Undo log的变化

1.InnoDB MVCC 简介

​ InnoDB是一个多版本的存储引擎:为了支持事务的一些特性诸如并发和回滚,它保持着被修改行的旧版本信息。这些信息被存储在一个被叫做回滚段( rollback segment) 的表空间中。InnoDB在回滚段中用这些信息来执行undo操作,以此支持事务回滚。它也用这些信息来构造行的更早的版本,以此支持一致性读(快照读)。

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

前置知识: 隔离级别

2.InnoDB 实现MVCC的方式

MVCC只在repeatable-read和read-committed两个隔离级别下才工作,其他两个隔离级别都和MVCC不兼容,因为read uncommitted总是读取最新的数据行,而不是符合当前事务版本的数据行,而serializeble则会对所有读取的行都加锁(与多版本 并发相悖)。

在REPEATABLE READ隔离级别下,InnoDB MVCC是如何操作的:

  • SELECT

    InnoDB 会根据以下两个条件检查每行记录 :

    a. InnoDB只查找版本早于当前事务版本的行数(也就是,行的系统版本号小于或等于事物的系统版本号),这样可以确保事务读取的行,要么是事务开始前已经存在,要么是事务自身插入或者修改的。

    b. 行的删除版本要么未定义,要么大于当前事务版本号。这样可以确保事务读取到的行,在事务开始前没有被删除。

  • INSERT

    InnoDB为新插入的每一行保存当前的系统版本号作为行版本号。

  • DELETE
    InnoDB为删除的每一行保存当前的系统版本号作为删除版本号。
  • UPDATE
    InnoDB为新插入的每一行保存当前的系统版本号作为行版本号,同时保存当前版本号直到原来的行作为删除标识。

MVCC在RR和RC隔离级别下的区别:在RR隔离级别下,一个事务只能读取到事务开始的那个时刻的数据快照,在RC隔离级别下,事务总是读取数据行的最新快照,即会产生不可重复读的问题。

RC是语句级多版本(事务的多条只读语句,创建不同的ReadView,代价更高),RR是事务级多版本(一个ReadView);

3.InnoDB行记录格式

InnoDB支持多种行格式,大同小异,以Compact行记录为例,

变长字段长度列表 NULL标识位 记录头信息(包含删除标记) RowID TransactionID Roll Pointer 列1数据 列2数据 …..

在内部,InnoDB为数据库中存储的每一行添加三个隐藏字段。

  • DB_TRX_ID: 表明插入或者修改这一行的最后一个事务的事务标识符。 如何查看行事务ID
  • DB_ROLL_PTR: 指向回滚段中的一个undo log记录,如果行被修改了,那么这个undo log记录包含的信息必须先于行修改被重新修改。
  • DB_ROW_ID: 单调递增的行ID。如果InnoDB自动生成了一个聚集索引,那么这个索引包含行ID值,否则DB_ROW_ID列不会出现在任何索引中。

delete在内部被当做update来对待,就是在行的特定位做一个标记,以表明这一行已经被删除。

可以把一条记录看成一个链表。

mysql innodb mvcc

mysql innodb mvcc

4.Read View与可见性

一致非锁定读,也可以称为快照读,即普通SELECT语句,既然是快照读,故 SELECT 的时候,会生成一个快照。

生成快照的时机:事务中第一次调用SELECT语句的时候才会生成快照,在此之前事务中执行的update、insert、delete操作都不会生成快照。

不同事务隔离级别下,快照读的区别:

READ COMMITTED 隔离级别下,每次读取都会重新生成一个快照,所以每次快照都是最新的,也因此事务中每次SELECT也可以看到其它已commit事务所作的更改;

REPEATED READ 隔离级别下,快照会在事务中第一次SELECT语句执行时生成,只有在本事务中对数据进行更改才会更新快照,因此,只有第一次SELECT之前其它已提交事务所作的更改你可以看到,但是如果已执行了SELECT,那么其它事务commit数据,你SELECT是看不到的。

简单来说,Read View记录读开始时,所有的活动事务,这些事务所做的修改对于Read View是不可见的。除此之外,所有其他的小于创建Read View的事务号的所有记录均可见。可见包括两层含义:

  • 记录可见,且Deleted bit = 0;当前记录是可见的有效记录。
  • 记录可见,且Deleted bit = 1;当前记录是可见的删除记录。此记录在本事务开始之前,已经删除。

4.1 事务链表

​ 事务在开始后到被提交的过程中,会被存储到事务链表中。当事务提交或回滚后,将其从事务链表中删除。

​ 事务35事务39事务40事务41trx_sys

4.2 Read View结构

在事务中执行第一条语句(查询或更新都可以)后,会生成一个Read View。

​ Read View主要包含3个成员:

  • low_limit_id:表示创建read view时,当前事务活跃读写链表最大的事务ID,即最近创建的除自身外最大的事务ID

  • up_limit_id:表示创建read view时,当前事务活跃读写链表最小的事务ID。

  • trx_ids:创建read view时,活跃事务链表里所有事务ID

例子:对于4.1中的事务40 low_limit_id=41,up_limit_id=35,trx_ids={35,39,40,41}

4.3 可见性判断

可见行判断是基于行的,所有数据行上都有最后操作的事务ID( DB_TRX_ID )。

  • 如果 DB_TRX_ID 小于 up_trx_id(查询开始时最小的活跃事务ID) 的记录,说明修改该行的事务在当前事务开启之前都已经提交完成,所以对当前事务来说,都是可见的。

  • 如果 DB_TRX_ID 大于 low_trx_id(查询开始时最大的活跃事务ID) 的记录,说明修改该行记录的事务在当前事务之后,所以对于当前事务来说是不可见的。

  • 如果 DB_TRX_ID 介于 low_trx_id与low_trx_id 之间,则需要区分隔离级别

    • RR级别要求可重复读,所以已经开始的事务链表中的事务的所有修改都是不可见的,所以对于当前事务来说是不可见的。

    • RC级别要求读最新的记录,所以已经开始的事务链表中的事务提交后是可见的。

5.Undo log格式

Undo log分为insert undo log 和update undo log。insert undo log对其他事务不可见,所以插入完成后就会丢弃。

MVCC相关的是update undo log。此处介绍的是update undo log的格式。

next 2字节,记录的是下一个undo log的位置
type_cmpl 1字节,记录的是Undo的类型,对于insert undo log 该值总是为11
*undo no
*table id 记录undo log所对应的表
info_bits
*DATA_TRX_ID 旧事务的ID
*DATA_ROLL_PTR 旧记录回滚段的指针

mysql innodb mvcc

5.1 insert undo log有什么用?

insert 需要回滚时可以用insert undo log 进行数据删除。

5.2 为什么insert undo log对其他事务不可见?

首次插入,不存在多版本问题,可以直接根据该行的隐藏事务ID来判断是否可见。

5.3 那第一条记录插入后的读取的都是当前行?

是的

6.各写操作下Undo log的变化

Undo Log的两个用处分别是:MVCC和Rollback。所以可以认为Undo log存储的是事务的逆操作(编辑一行存一条)。

可以认为当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条对应相反的update记录。实际不是,但是这样容易理解。

6.1 Insert操作

  • 产生一条insert undo log,并在事务提交后删除。

6.2 Update操作

  • 如果未更新主键列,在undo log中直接反向记录是如何update的。即update是直接进行的。
  • 如果更新了主键列,update分两部执行:先删除该行,再插入一行目标行。

6.3 Delete操作

  • 不会真实删除数据,而是把该行标记为删除,最终删除是由purge进行的。

6.4 Select

  • 读取记录行,如果当前记录不可见,根据db_roll_ptr回溯历史记录

InnoDB多版本(MVCC)实现简要分析

MySQL MVCC实现 &version=12020810&nettype=WIFI&fontScale=100&pass_ticket=lvYDkS697l2%2FqlJyvzV9O3xv0CkyvL1Nllw4n%2FZEIf9PD6D2JBaFFaJ2Bhg9Y2bg)

InnoDB undo log 漫游

《MySQL技术内幕 InnoDB存储引擎》

《高性能MySQL》


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

HTML 5 与 CSS 3 权威指南

HTML 5 与 CSS 3 权威指南

陆凌牛 / 机械工业出版社华章公司 / 2011-4-7 / 69.00

如果你是一位有前瞻性的web前端工作者,那么你一定会从本书中受益,因为它就是专门为你打造的。 《HTML 5与CSS 3权威指南》内容系统而全面,详尽地讲解了html 5和css 3的所有新功能和新特性;技术新颖,所有知识点都紧跟html 5与css 3的最新发展动态(html 5和css 3仍在不断完善之中);实战性强(包含246个示例页面),不仅每个知识点都配有精心设计的小案例(便于动手......一起来看看 《HTML 5 与 CSS 3 权威指南》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

URL 编码/解码
URL 编码/解码

URL 编码/解码