InnoDB锁笔记

1.   InnoDB主要使用行级锁(row lock),其行锁是通过在索引项上加锁而实现的,如果MySQL的执行计划没有用到索引,那么行锁也就无意义了

锁模式:

S锁: 允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。

X锁: 允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享读锁和排他写锁。

意向锁:数据库需要对细粒度的对象上锁,需要首先给粗粒度的对象上锁。在粗粒度对象上上的锁成为意向锁。innodb的意向锁包括共享意向表锁和排他意向表锁。

IS锁: 对记录加S锁之前必须先获取表的IS锁

IX锁: 事务对记录加X锁之前必须先获取表的IX锁

四种锁的兼容矩阵如下:

  

请求模式

当前模式

X

IX

S

IS

X

冲突

冲突

冲突

冲突

IX

冲突

兼容

冲突

兼容

S

冲突

冲突

兼容

兼容

IS

冲突

兼容

兼容

兼容

意向锁就是表级锁,会跟表锁之间有冲突。

行锁包括:

  • 间隙锁(Gap Lock),只锁间隙。表现为锁住一个区间(注意这里的区间都是开区间,也就是不包括边界值)。GAP锁的目的,是为了防止同一事务的两次当前读,出现幻读的情况.
  • 记录锁(Record Lock),只锁记录。表现为仅仅锁着单独的一行记录。
  • Next-Key锁(源码中称为Ordinary Lock),同时锁住记录和间隙。从实现的角度为record lock+gap lock,而且两种锁有可能只成功一个,所以next-key是半开半闭区间,且是下界开,上界闭。一张表中的next-key锁包括:(负无穷大,最小的第一条记录],(记录之间],(最大的一条记录,正无穷大)。[对于行的查询,都是采用该方法,主要目的是解决幻读的问题]
  • 插入意图锁(Insert Intention Lock),插入操作时使用的锁。在代码中,插入意图锁实际上是Gap锁上加了一个LOCK_INSERT_INTENTION的标记。也就是说insert语句会对插入的行加一个X记录锁,但是在插入这个行的过程之前,会设置一个Insert intention的Gap锁,叫做Insert intention锁。

MVCC: 当读取数据时如果碰到对象已经上了X锁就直接读取镜像数据。又因为事务隔离级别的不同,在不同事务隔离级别下读取的镜像也会不同。

临键锁:主要是解决幻读的问题, 是InnoDB的默认行锁. 

为什么是使用左开右闭? 因为索引是B+树, 使用右闭合,是因为新加的数据一般都是存在右边节点上........

InnoDB的行锁是通过给索引上的索引(聚集,非聚集)添加锁来实现的,  

只有通过索引条件进行数据索引, InnoDB才使用行级别锁, 否则的话会使用表锁(锁住所有记录).

意向锁: IX,IS是表锁,更多的时候可以认为是一个标记....

plus:

锁升级:

很多数据库如:SQL server就有锁升级的想象,但是innodb并没有锁升级。这是因为innodb根据事务访问的每个页对锁进行管理,采用位图方式,因此不管一个事务锁住页中的一行还是多个记录,其开销通常都是一样的。

猜你喜欢

转载自www.cnblogs.com/snow-man/p/10097695.html