mysql没索引怎么加锁 mysql有索引但是未命中( 五 )


请点击输入图片描述
Innodb锁机制InnoDB实现了两种类型的行锁 。
共享锁(S) :允许一个事务去读一行 , 阻止其他事务获得相同的数据集的排他锁 。
排他锁(X) :允许获得排他锁的事务更新数据,但是组织其他事务获得相同数据集的共享锁和排他锁 。
可以这么理解:
共享锁就是我读的时候,你可以读 , 但是不能写 。排他锁就是我写的时候,你不能读也不能写 。其实就是MyISAM的读锁和写锁 , 但是针对的对象不同了而已 。
除此之外InnoDB还有两个表锁:
意向共享锁(IS) :表示事务准备给数据行加入共享锁,也就是说一个数据行加共享锁前必须先取得该表的IS锁
意向排他锁(IX) :类似上面 , 表示事务准备给数据行加入排他锁,说明事务在一个数据行加排他锁前必须先取得该表的IX锁 。
意向锁是InnoDB自动加的,不需要用户干预 。
对于insert、update、delete , InnoDB会自动给涉及的数据加排他锁(X);对于一般的Select语句,InnoDB不会加任何锁,事务可以通过以下语句给显示加共享锁或排他锁 。
共享锁:select * from table_name where .....lock in share mode
排他锁:select * from table_name where .....for update
InnoDB行锁是通过给索引项加锁实现的,索引分为主键索引和非主键索引两种,如果 一条 sql语句操作了主键索引 , MySQL就会锁定这条主键索引;如果一条语句操作了非主键索引,MySQL会先锁定该非主键索引,再锁定相关的主键索引 , 如果没有索引,InnoDB会通过隐藏的聚簇索引来对记录加锁 。也就是说:如果不通过索引条件检索数据,那么InnoDB将对表中所有数据加锁,实际效果跟表锁一样 。
InnoDB对于行的查询都是采用了Next-Key Lock的算法,锁定的不是单个值,而是一个范围(GAP) 。上面索引值有1,3,5,8,11 , 其记录的GAP的区间如下:是一个 左开右闭 的空间(原因是默认主键的有序自增的特性,结合后面的例子说明)
(-∞,1],(1,3] , (3,5],(5,8] , (8,11],(11,+∞)
InnoDB对于行的查询都是采用了Next-Key Lock的算法 , 锁定的不是单个值,而是一个范围,按照这个方法是会和第一次测试结果一样 。但是,当查询的索引含有唯一属性的时候 , Next-Key Lock 会进行优化,将其降级为Record Lock,即仅锁住索引本身,不是范围 。
Next-Key Lock是行锁与间隙锁的组合 , 这样,当InnoDB扫描索引记录的时候,会首先对选中的索引记录加上行锁(Record Lock) , 再对索引记录两边的间隙加上间隙锁(Gap Lock) 。如果一个间隙被事务T1加了锁,其它事务是不能在这个间隙插入记录的 。
MySQL简单介绍——换个角度认识MySQL1、InnoDB存储引擎
Mysql版本=5.5 默认的存储引擎 , MySQL推荐使用的存储引擎 。支持事务,行级锁定,外键约束 。事务安全型存储引擎 。更加注重数据的完整性和安全性 。
存储格式 : 数据,索引集中存储 , 存储于同一个表空间文件中 。
InnoDB的行锁模式及其加锁方法: InnoDB中有以下两种类型的行锁:共享锁(读锁: 允许事务对一条行数据进行读?。┖?互斥锁(写锁: 允许事务对一条行数据进行删除或更新),对于update,insert , delete语句,InnoDB会自动给设计的数据集加互斥锁,对于普通的select语句,InnoDB不会加任何锁 。
InnoDB行锁的实现方式: InnoDB行锁是通过给索引上的索引项加锁来实现的,如果没有索引,InnoDB将通过隐藏的聚簇索引来对记录加锁 。InnoDB这种行锁实现特点意味着:如果不通过索引条件检索数据 , 那么InnoDB将对表中的所有记录加锁,实际效果跟表锁一样 。

推荐阅读