并发即指在同一时刻,多个操作并行执行。MySQL对并发的处理主要应用了两种机制——是“锁”和“多版本控制”。

锁分为读锁和写锁两种,也称作共享锁和排他锁。
因为多个读操作同时进行是不会破坏数据的,所以读锁是共享的,多个读操作可以同时进行,互不干扰。
为了防止多个写操作共同执行破坏数据,写锁是排他的,一个写锁会阻塞其它的写锁和读锁,进而保证同一资源在任何时刻只有一个写操作在执行,并防止其它用户读取正在写入的该资源。
在锁粒度方面,MySQL包括表锁和行锁两种类型。锁的粒度越小,越有利于对数据库操作的并发执行。但是管理锁消耗的资源也会更多。如果系统花费大量的时间来管理锁,而不是存储数据,那么系统的性能也会受到影响。
表锁会锁定整张表,它是开销最小的策略。诸如ALTER TABLE之类的语句会使用表锁。
行锁最大程度的支持并发操作,同时也带来了最大的开销。InnoDB实现了行锁。
在MySql中并不只是用锁来维护并发控制。

事务的隔离级别

事务的概念在此不多介绍。我觉得,也可以将事务看成是并发中的一部分——事务包含了一组操作,事务和事务之间可以并行执行。事务和事务之间的并发也和普通的并发操作一样会共享相同的资源,这样并发执行的事务之间就会相互影响。根据事务之间影响程度的不同,提出了事务的隔离级别这个概念,分别是READ
UNCOMMITTED、READ COMMITTED、REPEATABLE READ、SERIALIZABLE。
READ UNCOMMITTED就是一个事务对共享数据的修改马上就能够被另一个事务感知到,其实也就是没有对修改操作做任何特殊处理。
SERIALIZABLE是通过加锁的方式强制事务串行执行,这样可以避免幻读。但这种方式会带来大量锁争用问题。
READ COMMITTED和REPEATABLE READ是基于MVCC的方式实现的。

MVCC多版本并发控制

MySql对于事务之间并发控制的实现并不是简单的使用行级锁。MySql在读操作时并不加锁,只有在写操作时才会对修改的资源加锁。
MVCC保存了数据资源在不同时间点上的多个快照。根据事务开始的时间不同,每个事务看到的数据快照版本是不一样的。
InnoDB中的MVCC实现:存储引擎全局维护了一个系统版本号,每开启一个新的事务,这个系统版本号就会递增。事务开始时刻的系统版本号,会作为这个事务本身的版本号。在每行记录中,存储引擎又在每行的后面保存两个隐藏的列,分别保存这一行的开始版本号和过期版本号。在REPEATABLE
READ隔离级别下,MVCC的具体操作如下:

  • INSERT
    存储引擎为新插入的每一行保存当前的系统版本号作为这一行的开始版本号。

  • UPDATE
    存储引擎会新插入一行记录,当前的系统版本号就是新记录行的开始版本号。同时会将原来行的过期版本号设为当前的系统版本号。

  • DELETE
    存储引擎将删除的记录行的过期版本号设置为当前的系统版本号。

  • SELECT
    当读取记录时,存储引擎会选取满足下面两个条件的行作为读取结果。

    1. 读取记录行的开始版本号必须早于当前事务的版本号。也就是说,在当前事务开始之前,这条记录已经存在。在事务开始之后才插入的行,事务不会看到。

    2. 读取记录行的过期版本号必须晚于当前事务的版本号。也就是说,当前事务开始的时候,这条记录还没有过期。在事务开始之前就已经过期的数据行,该事务也不会看到。

通过上面的描述,可以看到在存储引擎中,同一时刻存储了一个数据行的多个版本。每个事务会根据自己的版本号和每个数据行的开始及过期版本号选择读取合适的数据行。
MVCC只在READ COMMITTED和REPEATABLE READ这两个级别下工作。

MySQL并发控制的更多相关文章

  1. 五分钟详解MySQL并发控制及事务原理

    在如今互联网业务中使用范围最广的数据库无疑还是关系型数据库MySQL,之所以用"还是"这个词,是因为最近几年国内数据库领域也取得了一些长足进步,例如以TIDB.OceanBase等 ...

  2. mysql 并发控制

    1.多个线程同时修改数据,存在数据不一致的情况,也就是并发控制的问题.2.mysql提供读锁和写锁,读锁之上可以再加读锁,不能加写锁,而写锁之上不能加任何锁.也就是说,读锁是共享的,写锁是排他的.3. ...

  3. mysql并发控制之快照读和当前读

    上一篇简单的介绍了下MVCC(多版本并发控制)的原理,MVCC会对事物内操作的数据做多版本控制,从而实现并发环境下事物对数据写操作的阻塞不影响读操作的性能.而这个多版本控制的实现是由undo log来 ...

  4. mysql并发控制之MVCC

    1.MVCC(Multiversion concurrency control) :多版本并发控制,当我们并发访问数据库(读或写)时,对事物内正在处理的数据做多版本控制,用以防止写操作的阻塞影响读操作 ...

  5. MySQL——并发控制(锁)

    核心知识点: 1.表锁和行级锁代表着锁的级别:读锁和写锁代表锁定真实类型. 2.读锁属于共享锁,共享同一资源,互不干扰:写锁属于排他锁,为了安全起见,写锁会阻塞其他的读锁和写锁. 3.表锁的开销最小, ...

  6. mysql并发控制之数据库锁

    1.mysql和redis的区别 mysql是一种关系型数据库,数据会最终存储在磁盘上.而redis是一种非关系型的nosql数据库,以key-value的形式存储数据,将数据存储在内存.从性能上来说 ...

  7. mysql—并发控制及事务

    并发控制 实现的并发访问的控制技术是基于锁: 锁分为表级锁和行级锁,MyISAM存储引擎不支持行级锁:InnoDB支持表级锁和行级锁: 锁的分类有读锁和写锁,读锁也被称为共享锁,加读锁的时候其他的人可 ...

  8. 深入理解MySQL的并发控制、锁和事务【转】

    本文主要是针对MySQL/InnoDB的并发控制和加锁技术做一个比较深入的剖析,并且对其中涉及到的重要的概念,如多版本并发控制(MVCC),脏读(dirty read),幻读(phantom read ...

  9. 深入理解Mysql——锁、事务与并发控制

    本文对锁.事务.并发控制做一个总结,看了网上很多文章,描述非常不准确.如有与您观点不一致,欢迎有理有据的拍砖! mysql服务器逻辑架构 每个连接都会在mysql服务端产生一个线程(内部通过线程池管理 ...

随机推荐

  1. aspx代码审计-2

    今天和大家分享一下aspx网站的代码审计,漏洞类型为:未授权访问和任意文件下载. 本文作者:i春秋签约作家——非主流 今天看的源码文件就不共享给大家了,本文只作学习只用. 还是先看我们的文件夹目录和d ...

  2. Python中复制、深拷贝和浅拷贝的区别

    深拷贝定义(deepcopy) 在Python中,由于一切皆对象,所以任何变量都可以被引用,也即可以被赋值给任何变量.但是在Python中,给变量赋值,是区分的,一般情况下,Python中的变量赋值都 ...

  3. 【3】JMicro微服务-服务超时,重试,重试间隔

    如非授权,禁止用于商业用途,转载请注明出处作者:mynewworldyyl 接下来的内容都基于[2]JMicro微服务-Hello World做Demo 微服务中,超时和重试是一个最基本问题下面Dem ...

  4. 2016级算法期末上机-F.中等·AlvinZH's Fight with DDLs II

    1118 AlvinZH's Fight with DDLs II 思路 中等题,贪心. 理解题意,每次攻击中,可以使某个敌人生命值-1,自己生命值减去∑存活敌人总攻击力. 贪心思想,血量少攻击高的要 ...

  5. 此博客不再维护,请移步http://daiweilai.github.io/

    此博客不再维护,请移步新博客 http://daiweilai.github.io/ 新开的这个博客系统,托管在了Github.io上,喜闻乐见的Jekll加借鉴(抄袭)的精美主题构建而成,反正样子应 ...

  6. (转)linux运维必会MySQL企业面试题

    linux运维必会MySQL企业面试题  老男孩教育运维班全体学员MySQL必会企业面试题最实战.最细致.最落地的运维实训基地,老男孩教育连续多年国内平均就业工资最高! 数据库的重要性是所有技术里最核 ...

  7. kafka多线程消费topic的问题

    案例: topic:my-topic,分区:6 消费者:部署三台机器,每台机器上面开启6个线程消费. 消费结果:只有一台机器可以正常消费,另外两台机器直接输出六条告警日志: No broker par ...

  8. BigDecimal加减乘除运算(转)

    java.math.BigDecimal.BigDecimal一共有4个够造方法,让我先来看看其中的两种用法: 第一种:BigDecimal(double val) Translates a doub ...

  9. 【MPI】执行mpiexec出错

    运行mpiexec提示mpiexec_mic: cannot connect to local mpd (/tmp/mpd2.console_jzhang); possible causes: 1. ...

  10. hibernate配置hbm2ddl.auto的四个参数

    <!-- Drop and re-create the database schema on startup --> <!-- hbm(hibernatemapping) ,ddl( ...