Mysql中那些锁机制之InnoDB

我们知道mysql在曾经。存储引擎默认是MyISAM。可是随着对事务和并发的要求越来越高,便引入了InnoDB引擎。它具有支持事务安全等一系列特性。

InnoDB锁模式

InnoDB实现了两种类型的行锁。

共享锁(S:同意一个事务去读一行,阻止其它事务获得同样的数据集的排他锁。

排他锁(X:同意获得排他锁的事务更新数据,可是组织其它事务获得同样数据集的共享锁和排他锁。

能够这么理解:

共享锁就是我读的时候,你能够读,可是不能写。排他锁就是我写的时候。你不能读也不能写。事实上就是MyISAM的读锁和写锁,可是针对的对象不同了而已。

除此之外InnoDB还有两个表锁:

意向共享锁(IS:表示事务准备给数据行增加共享锁。也就是说一个数据行加共享锁前必须先取得该表的IS锁

意向排他锁(IX:类似上面,表示事务准备给数据行增加排他锁,说明事务在一个数据行加排他锁前必须先取得该表的IX锁。

InnoDB行锁模式兼容列表:

注意:

当一个事务请求的锁模式与当前的锁兼容。InnoDB就将请求的锁授予该事务;反之假设请求不兼容,则该事务就等待锁释放。

意向锁是InnoDB自己主动加的。不须要用户干预。

对于insert、update、delete,InnoDB会自己主动给涉及的数据加排他锁(X);对于一般的Select语句,InnoDB不会加不论什么锁,事务能够通过下面语句给显示加共享锁或排他锁。

共享锁:select * from table_name where .....lock in share mode

排他锁:select * from table_name where .....for update

增加共享锁的样例:

利用select ....for update增加排他锁

锁的实现方式:

InnoDB行锁是通过给索引项加锁实现的。假设没有索引,InnoDB会通过隐藏的聚簇索引来对记录加锁。

也就是说:假设不通过索引条件检索数据。那么InnoDB将对表中全部数据加锁。实际效果跟表锁一样。

行锁分为三种情形:

Record lock :对索引项加锁。即锁定一条记录。

Gap lock:对索引项之间的‘间隙’、对第一条记录前的间隙或最后一条记录后的间隙加锁,即锁定一个范围的记录,不包括记录本身

Next-key Lock:锁定一个范围的记录并包括记录本身(上面两者的结合)。

注意:InnoDB默认级别是repeatable-read级别,所以以下说的都是在RR级别中的。

之前一直搞不懂Gap Lock和Next-key Lock的差别,直到在网上看到一句话豁然开朗,希望对各位有帮助。

Next-Key Lock是行锁与间隙锁的组合。这样,当InnoDB扫描索引记录的时候。会首先对选中的索引记录加上行锁(Record Lock),再对索引记录两边的间隙加上间隙锁(Gap Lock)。

假设一个间隙被事务T1加了锁,其他事务是不能在这个间隙插入记录的。

干巴巴的说没意思,我们来看看详细实例:

如果我们有一张表:

+----+------+

| id | age  |

+----+------+

|  1 |    3 |

|  2 |    6 |

|  3 |    9 |

+----+------+

表结构例如以下:

CREATE TABLE `test` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`age` int(11) DEFAULT NULL,

PRIMARY KEY (`id`),

KEY `keyname` (`age`)

) ENGINE=InnoDB AUTO_INCREMENT=302 DEFAULT CHARSET=gbk ;

这样我们age段的索引就分为

(negative infinity, 3],

(3,6],

(6,9],

(9,positive infinity);

我们来看一下几种情况:

1、当事务A运行下面语句:

mysql> select * from fenye where age=6for update ;

不仅使用行锁锁住了对应的数据行。同一时候也在两边的区间,(5,6]和(6,9] 都增加了gap锁。

这样事务B就无法在这个两个区间insert进新数据,可是事务B能够在两个区间外的区间插入数据。

2、当事务A运行

select * from fenye where age=7 for update ;

那么就会给(6,9]这个区间加锁,别的事务无法在此区间插入或更新数据。

3、假设查询的数据不再范围内,

比方事务A运行 select * from fenye where age=100 for update ;

那么加锁区间就是(9,positive infinity)。

小结:

行锁防止别的事务改动或删除,GAP锁防止别的事务新增。行锁和GAP锁结合形成的的Next-Key锁共同攻克了RR级别在写数据时的幻读问题。

何时在InnoDB中使用表锁:

InnoDB在绝大部分情况会使用行级锁,由于事务和行锁往往是我们选择InnoDB的原因,可是有些情况我们也考虑使用表级锁。

1、当事务须要更新大部分数据时。表又比較大。假设使用默认的行锁,不仅效率低。并且还easy造成其它事务长时间等待和锁冲突。

2、事务比較复杂。非常可能引起死锁导致回滚。

死锁:

我们说过MyISAM中是不会产生死锁的,由于MyISAM总是一次性获得所需的所有锁,要么所有满足。要么所有等待。

而在InnoDB中。锁是逐步获得的。就造成了死锁的可能。

在上面的样例中我们可以看到。当两个事务都须要获得对方持有的锁才可以继续完毕事务,导致两方都在等待。产生死锁。

发生死锁后,InnoDB一般都能够检測到,并使一个事务释放锁回退。还有一个获取锁完毕事务。

避免死锁:

有多种方法能够避免死锁,这里仅仅介绍常见的三种:

1、假设不同程序会并发存取多个表,尽量约定以同样的顺序訪问表。能够大大减少死锁机会。

2、在同一个事务中。尽可能做到一次锁定所须要的全部资源,降低死锁产生概率;

3、对于很easy产生死锁的业务部分,能够尝试使用升级锁定颗粒度,通过表级锁定来降低死锁产生的概率;

參考:

Innodb中的事务隔离级别和锁的关系

MySQL InnoDB锁机制(二)

Innodb锁机制:Next-Key Lock 浅谈

深入浅出Mysql数据库开发、优化与管理维护.第二版

时间: 2024-10-08 20:41:31

Mysql中那些锁机制之InnoDB的相关文章

Mysql中那些锁机制之MyISAM

说到锁机制之前,先来看看Mysql的存储引擎,毕竟不同的引擎的锁机制也随着不同. 三类常见引擎: MyIsam :不支持事务,不支持外键,所以访问速度快.锁机制是表锁,支持全文索引 InnoDB :支持事务.支持外键,所以对比MyISAM,InnoDB的处理效率差一些,并要占更多的磁盘空间保留数据和索引.锁机制是行锁,不支持全文索引 Memory:数据是存放在内存中的,默认哈希索引,非常适合存储临时数据,服务器关闭后,数据会丢失掉. 如何选择存储引擎: MyISAM:应用是以读操作和插入操作为主

Mysql中的锁机制

原文:http://blog.csdn.net/soonfly/article/details/70238902 锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除传统的 计算资源(如CPU.RAM.I/O等)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所有数据库必须解决的一 个问题,锁冲突也是影响数据库并发访问性能的一个重要因素.从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂.本章我们着重讨论MySQL锁机制 的特点,常见的锁问题

【mysql】mysql中的锁机制

一.分类 MySQL的锁机制不同的存储引擎支持不同的锁机制,分为表级锁.行级锁.页面锁.MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking):BDB存储引擎采用的是页面锁(page-level locking),但也支持表级锁:InnoDB存储引擎既支持行级锁(row-level locking),也支持表级锁,但默认情况下是采用行级锁 表级锁:开销小,加锁快:不会出现死锁:锁定粒度大,发生锁冲突的概率最高,并发度最低. 行级锁:开销大,加锁慢:会出现死锁:

mysql中的锁机制之概念篇

锁的概念 ①.锁,在现实生活中是为我们想要隐藏于外界所使用的一种工具. ②.在计算机中,是协调多个进程或线程并发访问某一资源的一种机制. ③.在数据库当中,除了传统的计算资源(CPU.RAM.I/O等等)的争用之外,数据也是一种供许多用户共享访问的资源. ④.如何保证数据并发访问的一致性.有效性,是所有数据库必须解决的一个问题. ⑤.锁的冲突也是影响数据库并发访问性能的一个重要因素. MySQL锁的概述 相对于其它数据库而言,MySQL的锁机制比较简单,其最 显著的特点是不同的存储引擎支持不同的

mysql中的锁机制之悲观锁和乐观锁

1.悲观锁? 悲观锁顾名思义就是很悲观,悲观锁认为数据随时就有可能会被外界进行修改,所以悲观锁一上来就会把数据给加上锁.悲观锁一般都是依靠关系型数据库提供的锁机制,然而事实上关系型数据库中的行锁,表锁不论是读写锁都是悲观锁. 2.乐观锁? 乐观锁顾名思义,就是很乐观,每次自己操作数据的时候认为没有人会来修改它,所以不会去对数据进行加锁.但是在更新的时候会去判断在此期间数据有没有被修改,需要用户自己去实现乐观锁.乐观锁不会发生并发抢占资源,只有在提交操作的时候检查是否违反数据完整性. 2.1.为什

MySQL中的锁

数据库中有很多锁,但锁是为了解决什么问题?具体都有哪些锁呢?这篇文章简单对MySQL中的锁做了一个总结 一.锁的设计是为了解决什么问题? 当多用户读写数据的时候,就有可能会出现同一时刻对同一条数据的读写,如果是大家都只是对同一条数据进行读,无所谓,大家读到数据都是一样的,但当有的想要读取数据,有的想要修改数据的时候,或者大家都想要修改数据的时候就会出现问题.比如有一行数据现在值是5,同一时刻有两个用户都想要修改这行数据,用户1和用户2此刻读到的数据都是5,用户1在数据5的基础上加了1变成6,并将

MySQL数据库InnoDB存储引擎中的锁机制

MySQL数据库InnoDB存储引擎中的锁机制    http://www.uml.org.cn/sjjm/201205302.asp   00 – 基本概念 当并发事务同时访问一个资源的时候,有可能导致数据不一致.因此需要一种致机制来将访问顺序化. 锁就是其中的一种机制.我们用商场的试衣间来做一个比喻.试衣间供许多消费者使用.因此可能有多个消费者同时要试衣服.为了避免冲突,试衣间的门上装了锁.试衣服的人在里边锁住,其他人就不能从外边打开了.只有里边的人开门出来,外边的人才能进去. - 锁的基本

MySQL中的锁(表锁、行锁)

锁是计算机协调多个进程或纯线程并发访问某一资源的机制.在数据库中,除传统的计算资源(CPU.RAM.I/O)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所在有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素.从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂. 概述 相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制. MySQL大致可归纳为以下3种锁: 表级锁:开销小,加锁快:不会出

转载 深入浅出mysql事务处理和锁机制

1. 事务处理和并发性 1.1. 基础知识和相关概念 1 )全部的表类型都可以使用锁,但是只有 InnoDB 和 BDB 才有内置的事务功能. 2 )使用 begin 开始事务,使用 commit 结束事务,中间可以使用 rollback 回滚事务. 3 )在默认情况下, InnoDB 表支持一致读. SQL 标准中定义了 4 个隔离级别: read uncommited , read commited , repeatable read , serializable . read uncomm