(二)MySQL InnoDB锁模型

MySQL InnoDB锁模型

(一)MySQL InnoDB事务模型

(二)MySQL InnoDB锁模型

(三)MySQL InnoDB非锁定一致性读与锁定读

(四)MySQL InnoDB锁类型及幻象读问题

(五)MySQL InnoDB中各类语句加锁方式

(六)事务的提交与回滚极死锁检测、处理和预防

前边已经提到过S锁、X锁、行锁等概念。这里详细介绍一下InnoDB中的锁模型。

共享锁与排它锁

InnoDB实现了两类标准的行锁:共享锁(S锁)和排它锁(X锁),以到达对资源并发访问的目的。其中S锁允许持有锁的事务读取一行,而X锁允许持有锁的事务更新或者删除一行。X锁与S锁的兼容性如下图所示。也即,如果事务T1持有了行R上的X锁则另外一个事务T2请求行R上的X锁或S锁均会被阻塞。如果事务T1持有行R上的S锁则另外一个事务T2请求行R上的X锁会被阻塞而请求行R上的S锁能立即成功。

 

X

S

X

Conflict

Conflict

S

Conflict

Compatible

意向锁

实际上InnoDB支持多粒度的锁,也即,除了行锁外还支持表锁,表锁通过意向锁实现,用以提示事务即将对表中的行添加什么样的锁。有两种类型的表所:IS锁和IX锁,前者用以表明事务T将要在表t的行上设置S锁,后者用以表明事务T将要在表t的行上设置X锁。比如:SELECT...LOCK IN SHARE MODE会在表t上请求加IS锁,而SELECT...FOR UPDATE会在表t上加IX锁。意向锁协议如下:事务在表t的行上获取S锁前必须先要获得表上的IS锁;事务在表t的行上获取X锁之前必须先要获得表上的IX锁。最终各类锁的兼容性规则个总结如下:

 

X

IX

S

IS

X

Conflict

Conflict

Conflict

Conflict

IX

Conflict

Compatible

Conflict

Compatible

S

Conflict

Conflict

Compatible

Compatible

IS

Conflict

Compatible

Compatible

Compatible

若事务当前请求的锁与其他事务中已经存在的锁冲突则会阻塞直到已存在的锁被释放,否则能立即获取到。意向锁并不会互相阻塞(全表锁,如LOCK TABLES...WRITE除外),其目的在于显示某事务正在或者将要锁定表中的某行。

死锁

不同事务锁之间的相互等待可能造成死锁。一个典型的死锁例子:

(二)MySQL InnoDB锁模型_第1张图片

SESSION A 中的事务首先获取i=3这一行上的S锁,接下来SESSION B中的事务请求i=3这一行上的X锁,由于X锁与S锁不兼容导致阻塞等待。此时SESSION A中的事务又请求i=3这一行上的X锁,由于SESSION B中请求的该行上的X锁正在等待SESSION A释放该行上的S锁,而SESSION A中持有的S锁因SESSION B请求的X锁而不能升级为X锁,从而导致死锁发生。此时InnoDB选择代价较小的事务回滚释放其持有和请求的锁来解除死锁。

除了真正检测到“相互等待”造成的死锁外,还存在另外一种形式的“死锁”。InnoDB使用等待图来发现死锁,而当wait-for列表中的事务量达到LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK设置的量(默认200)时也会认为发生了“死锁”。此时可在SHOW ENGINE INNODB STATUS的输出中看到 “TOO DEEP OR LONG SEARCH IN THE LOCK TABLE WAITS-FOR GRAPH, WE WILL ROLL BACK FOLLOWING TRANSACTION” 这么一行内容。还有,当wait-for列表中的事务拥有的锁超过LOCK_MAX_N_STEPS_IN_DEADLOCK_CHECK(默认1000000)时也会认为发生了“死锁”。

你可能感兴趣的:(MySQL,InnoDB,Lock)