​目录


1.行锁:索引加锁

2.意向锁

3.间隙锁

4.MVCC机制

行锁


InnoDB通过多版本并发控制MVCC来支持事务

InnoDB的设计是为了在处理大数据量的时候得到最好的性能。InnoDB存储引擎维护了一个它自己的缓冲区,用来存储数据和索引。InnoDB将表和索引存储在一个表空间中,这个表空间可能由不同的文件组成。而MyISAM存储引擎的表中每个表都存在一个独立的文件里面。

InnoDB事务模型是将传统的两阶段封锁协议同多版本数据库特性相结合。它采用加行级锁和查询不加锁。

InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的。

InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁。

很显然,在使用范围条件检索并锁定记录时,InnoDB这种加锁机制会阻塞符合条件范围内键值的并发插入,这往往会造成严重的锁等待。因此,在实际应用开发中,尤其是并发插入比较多的应用,我们要尽量优化业务逻辑,尽量使用相等条件来访问更新数据,避免使用范围条件。

意向锁


InnoDB支持多种上锁粒度,它允许同时加行锁和表锁。为了支持多粒度锁,引入了一个新的锁,意向锁。意向锁是加在表上的锁。意向锁就是表明某个事务之后要对这个表上的某个行加该类型的锁。

共享意向锁IS,表明事务T将要在表T的某些行上加S锁。

排他意向锁IX,表明事务T将要在表T的某些行上加X锁

意向锁协议是:

       在某个事务请求行上的S锁之前,它必须先得到该行所在表的IS锁或更强的锁。

在某个事务请求行上的X锁之前,它必须先得到该行所在表的IX锁。

一致性非上锁读


InnoDB使用多版本的方式来控制一致性读,也就是说,给某个查询在该时刻的一个数据库的快照。这个查询可以看到这个时刻以前由其它事务提交的操作,而看不到之后做的改变或还未提交的改变。这个规则的唯一例外就是,事务可以看到本事务之前所做的还未提交的操作。

这个规则导致了下面的异常:如果你更新了某个表里面的行,使用SELECT将可以看见最新更新的行和老版本的行。如果其它事务同时更新相同的表,那么你就可能看到根本不可能在数据库中存在的状态。

如果在某人的REPEATABLE READ隔离级别下的话,所有同一事物的所有一致性读都是读的第一次查询时建立的快照。如果想得到最新的快照的话,那么需要提交当前的事务,然后再开始新的查询。

注意:DROP TABLE 和ALTER TABLE语句不使用一致性读。因为DROP TABLE的话,MYSQL不能使用已经删除了的表。而ALTER TABLE的时候,MYSQL是将原来的表复制一份,然后删除掉原来的表。

间隙锁


Next-Key Locking:避免幻象

      当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的 索引项加锁;对于键值在条件范围内但并不存在的记录,叫做“间隙(GAP)”,InnoDB也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁 (Next-Key锁) 

        在行级锁中,InnoDB使用一种称为next-key locking的算法。当检索表的一个索引的时候,它对遇到的索引记录加SX锁。因此行级锁实际上是索引记录锁。

       InnoDB在索引记录上加锁的时候也影响了索引记录前的‘gap’。如果一个用户拥有索引上某个记录RSX锁,另一个用户不能马上在记录R前插入一个新的索引记录。这样就可以避免幻象的出现。

Next-key lock是Record lock与Gap lock相结合后的锁。Next-key首先会使用Gap lock锁定范围,然后使用Record lock锁定具体的行。这是REPEATABLE-READ隔离级别的默认处理方式。

MVCC实现机制


不再单纯的使用行锁来进行数据库的并发控制,取而代之的是,把数据库的行锁与行的多个版本结合起来,只需要很小的开销,就可以实现非锁定读,从而大大提高数据库系统的并发性能。

为了实现mvcc, innodb对每一行都加上了两个隐含的列,其中一列存储行被更新的”时间”,另外一列存储行被删除的”时间”. 但是innodb存储的并不是绝对的时间,而是与时间对应的数据库系统的版本号。

每当一个事务开始的时候,innodb都会给这个事务分配一个递增的版本号,所以版本号也可以被认为是事务号.对于每一个”查询”语句,innodb都会把这个查询语句的版本号同这个查询语句遇到的行的版本号进行对比,然后结合不同的事务隔离等级,来决定是否返回该行.

mvcc优缺点


在读取数据时,innodb几乎不用获取任何锁,在每个查询通过版本检查,只获取需要的数据版本,提高系统并发度

缺点:为了实现多版本,innodb必须对每行增加相应字段来存储版本信息,同时需要维护每一行的版本信息,而且

在检索行的时候,需要进行版本的比较,因而减低了查询效率;innodb还需要定期清理不再需要的行版本,及时回收

空间,这也增加开销;

资料


MySQL加锁处理分析:http://hedengcheng.com/?p=771

InnoDB并发事务的更多相关文章

  1. MySQL Innodb 并发涉及参数

    1 参数作用 MySQL的各个插件式引擎中,都会对事务及线程做一定的处理和优化.在Innodb引擎中,总是尝试保持 innodb内 操作系统的线程数(暂命名为innodb_thread) 应该小于或等 ...

  2. 事务特性,事务的隔离级别,并发事务可能出现的问题,spring事务 数据库锁

    1.0 事务特性(ACID) Atomicity:原子性,一个事务不可以被拆分 Consistency:一致性,在事务执行前数据库的数据处于正确的状态,而事务执行完成后数据库的数据还是处于正确的状态, ...

  3. Spring 并发事务的探究

    前言 在目前的软件架构中,不仅存在单独的数据库操作(一条SQL以内,还存在逻辑性的一组操作.而互联网软件系统最少不了的就是对共享资源的操作.比如热闹的集市,抢购的人群对同见商品的抢购由一位售货员来处理 ...

  4. MySQL 并发事务问题以及事务的隔离级别

    一.并发事务处理带来的问题 相对于串行处理,并发事务(InnoDB)处理能大大增加数据库资源的利用率,提高数据库系统的事务吞吐量,从而可以支持更多用户. 但并发事务处理也会带来一些问题,主要有一下几种 ...

  5. 一文说清 InnoDB 的事务机制

    我们从一个转账的故事开始. 隔壁小王从美团上找到了一家水饺店,准备中午吃水饺.下单成功,支付20元. 商家这里响了一下:叮叮,您有美团外卖新订单啦,请及时处理.水饺一份,好嘞,下锅. 很快小王吃到外卖 ...

  6. InnoDB关于事务、锁、MVCC专题

    目录 并发所带来的的问题 脏写 脏读 不可重复读 幻读 事务 事务的特性 事务的四种隔离级别 锁 为什么要加锁 InnoDB的七种锁 不同事务RR和RC下加锁的规则 MVCC mvcc进一步提高并发 ...

  7. mysql的innodb中事务日志ib_logfile

    mysql的innodb中事务日志ib_logfile事务日志或称redo日志,在mysql中默认以ib_logfile0,ib_logfile1名称存在,可以手工修改参数,调节开启几组日志来服务于当 ...

  8. Linq无聊练习系列8---开放式并发事务,null和 DateTime,string操作练习

    /*********************开放式并发事务,null和 DateTime,string操作练习**********************************/ //所谓并发,就是 ...

  9. Mysql锁机制--并发事务带来的更新丢失问题

    Mysql 系列文章主页 =============== 刚开始学习 Mysql 锁的时候,觉得 Mysql 使用的是行锁,再加上其默认的可重复读的隔离级别,那就应该能够自动解决并发事务更新的问题.可 ...

随机推荐

  1. php无法连接mongodb 3.0问题解决

    1 几个常用的role root mongodb最高权限 userAdmin 自己建立的数据库账号管理权限 read 只读权限 readWrite 可读可写 2 遭遇的梗 为数据库建立了账号,php死 ...

  2. entropy 压缩信息的熵更加高 实际上英文文本的熵大概只有4.7比特

    https://en.wikipedia.org/wiki/Entropy_(information_theory) https://zh.wikipedia.org/wiki/熵(信息论) 熵的概念 ...

  3. java javassis crack class

    java javassis crack class java 反编译 android 反编译   1. jad http://varaneckas.com/jad/jad158e.linux.inte ...

  4. 前端基础-html(2)

    一.字体标签 字体标签包含:h1~h6.<font>.<u>.<b>.<strong>.<em>.<sup>.<sub&g ...

  5. php 使用sendmail发送邮件

    php 使用sendmail发送邮件 1.配置php.ini SMTP=smtp.163.com sendmail_from = 17760273453@163.com sendmail_path = ...

  6. 通过profile优化SQL语句

    开启profile优化SQL语句:set profiling=1;执行SQL语句show profiles;show profile for query 2;//根据query_id 查看某个查询的详 ...

  7. centos7 Mysql5.6 升级Mysql5.7

    1 2. 卸载Mysql5.6 ,一共有三个包 要卸载: (1)先卸载mysql-server包 : 执行命令  yum remove mysql mysql-server (2)再卸载mysql-c ...

  8. PS批量修改照片大小

    最近发现一个好玩的东西,分享一下懒人的做法 1.先打开一张图片,调出动作面板 2.新建动作,开始记录. 3.按Ctrl + Alt + I 或者选择图像菜单----图像大小,调出修改图像大小对话框. ...

  9. Oracle11g用户频繁锁定并且解锁后不允许登录

    原因有可能是oracle的密码过期机制导致的:一.由于Oracle中默认在default概要文件中设置了“PASSWORD_LIFE_TIME=180天”所导致.解决办法:1.查看用户用的哪种prof ...

  10. loadrunder之脚本篇——action分类

    Action分类 l . Vuser_init 2. Vuser_end 3.  Action 在lr中用户的初始化操作应该存放在Vuser_init中.用户的结束操作存放在Vuser_end中.因为 ...