Mysql Innodb 锁、事务笔记【待整理】

锁类型

表级别、行级别

共享锁(S 读锁)

排他锁(X 写锁)

1.读锁与读锁相互兼容

2.写锁与任何锁(读锁及写锁)都不兼容

表级别

表级别 innodb 还支持意向锁:

意向共享锁(IS 意向读锁)

意向排他锁(IX 意向写锁)

1.意向锁之间相互兼容

2.意向锁于非意向锁之间遵循 读写锁的兼容模式

3.意向锁含义:想要获取某张表的某几行的 锁,需要在行的上一级 表上加相应的意向锁,设计目的是在一个事务中揭示下一行将被请求的锁类型(不是很理解???)

select显示加锁:

1.select … for update; —显示加写锁

2.select … lock in share mode; —显示加读锁 

锁粒度

表锁

锁整张表 mysql alter

行锁

事务

事务隔离级别

读未提交 read uncommitted

读已提交 read committed (锁定一致性读)

可重复度 repeatable read (非锁定一致性读)

可串行化 serializable

多版本并发控制 mvcc(快照数据)

1.行锁实现方式

2.只在 读已提交、可重复度 两种隔离级别生效,因为读未提交无关事务,能看到所有修改;可串行化隔离级别最高,在每一行上加锁,无操作空间

3.innodb 每条记录最后都额外有两个字段:创建版本、删除版本(存的是版本号,每开启一个事务 版本号都会自增,保证这个版本号对于每个事务都有唯一性,且能识别先后顺序)

4.可重复度(repeatable read)隔离级别下单 mvcc 实现:

select:获取创建版本在当前版本之前(小于或者等于),删除版本在当前版本之后(大于)或者未定义删除版本号的记录,保证这条记录在当前事务开启之前就已被创建,且当前事务开启的时候还未被删除或修改

insert:插入记录行的版本号设置成当前事务的版本号

update:愿记录的删除版本号设置成当前版本号,再插入一条修改后的最新的记录,创建版本为当前版本号,删除版本号不定义

delete:设置删除记录的删除版本号为当前版本

Mysql Innodb 锁、事务笔记【待整理】

左右两事务都未提交,左边分别 insert 和 update 表test,但右边事务中select始终得到的是食物开启前的数据,因为是可重复读,mvcc控制的效果,当两边事务都提交后,select出来的结果就一致了

5.通过可重复读的select规则,读已提交的select规则不难推测只要版本号的判断上松一点即可,获取删除版本号为定义的就是最新的记录,及其他事务操作后的记录就也能被当前事务获取到了

6.mvcc 极大的提高了数据库的并发性,因为查询无需等待锁的释放,无需占用和等待表上的锁

锁定一致性读

  1.自增长字段:

  当表中存在自增长字段,两个事务同时插入一条记录

Mysql Innodb 锁、事务笔记【待整理】

  两边的事务都未提交,但两边都获取到了正确的自增长id,即右边事务在未提交情况下获取到了左边事务未提交情况下都id。

  因为自增长列有一个特殊的表锁机制:auto-inc locking。这个锁并不是在事务提交时释放,而是在有自增长值的sql语句执行完后立即释放

Mysql Innodb 锁、事务笔记【待整理】

所以即使左边的事务rollback了,插入操作被取消了,但id 的自增长结果还是被保留了

2.auto-inc locking 机制也是提高了自增长值的插入性能,避免多个事务同时插入数据是互相等待对方锁的释放

锁的算法

1.record lock:单个行上的锁

2.gap lock:间隙锁

3.next-key lock:临间锁(record lock + gap lock)

如果是聚簇缩影(唯一主键),会降级为record lock

如果是辅助索引,repeatable read 隔离级别下会添加间隙锁

  例:

Mysql Innodb 锁、事务笔记【待整理】

  Indextest 表中 a为主键,b为辅助索引,此时针对辅助索引b分为了(1, 3],(3, 6],(6, 8],这些区间(等于的区间放在前面还是后面有不同的模式),如果事务 T1 锁住了b=3 这条记录,那相应的 b=3 所在的前后两个区间( (1, 3],(3, 6] )都会被锁住,事务 T2 想要在这些范围内加锁是就需要等待 T1 事务结束,释放锁。

Mysql Innodb 锁、事务笔记【待整理】

如图,当左边事务提交后,右边事务才活渠道 数据;

因为repeatable read 隔离级别下

Mysql Innodb 锁、事务笔记【待整理】

  采用 next-key lock算法,read committed 隔离级别仅采用 record lock算法,所以关闭如上功能只要吧隔离级别改为 read committed 即可,

隔离级别

Mvcc

锁算法

Read uncommitted

   

Read committed

record lock

Repeatable read

Next-key lock

Serializable

 

 

死锁

  如图:

Mysql Innodb 锁、事务笔记【待整理】

  T1,T2 分别锁上 a = 1,a = 3 的记录,T1在获取 a = 3时由于 T2 未释放,T1 阻塞(图上是因为T2报死锁异常,T2结束释放了锁才看到了返回,此处不详细描述了),T2再去获取 a = 1的记录时,由于 T1持有了 a = 1的锁,并没有释放,再阻塞着,所以T2 等待 T1 释放 a = 1 的锁,也阻塞了,这样 T1、T2 都在等待对方释放锁而阻塞,就死锁了,所以报死锁异常了

上一篇:Linux 锁介绍


下一篇:linux-进程的替换exec函数族