最近碰到很多锁问题,所以解决了后,仔细再去浏览了关于锁的书籍,整理以下:
1,锁的种类
Innodb存储引擎实现了以下2种标准的行级锁:
? 同享锁(S lock),允许事务读取1行数据。
? 排它锁(X lock),允许事务删除或更新1行数据。
当1个事务获得了行r的同享锁,那末另外1个事务也能够立即获得行r的同享锁,由于读取并未改变行r的数据,这类情况就是锁兼容。但是如果有事务想取得行r的排它锁,则它必须等待事务释放行r上的同享锁―这类情况就是锁不兼容,2者兼容性以下表格所示:
排它锁和同享锁的兼容性 | ||
| X 排它锁 | S 同享锁 |
X 排它锁 | 冲突 | 冲突 |
S 同享锁 | 冲突 | 兼容 |
2,锁的扩大
Innodb存储引擎支持多粒度锁定,这类锁定允许在行级别上的锁和表级别上的锁同时存在。为了支持在不同粒度上进行加锁操作,InnoDB存储引擎支持1种额外的锁方式,就是意向锁。意向锁是表级别的锁,其设计目的主要是为了在1个事务中揭露下1即将被要求的锁的类型。它也分为两种:
? 意向同享锁(IS Lock),事务想要取得1个表中某几行的同享锁。
? 意向排它锁(IX Lock),事务想要取得1个表中某几行的排它锁。
由于InnoDB支持的是行级别锁,所以意向锁其实不大会阻塞除全表scan以下的任何要求。同享锁、排它锁、意向同享锁、意向排它锁相互之前都是有兼容/互斥关系的,可以用1个兼容性矩阵表示(y表示兼容,n表示不兼容),以下所示:
| X 排它锁 | S 同享锁 | IX 意向排它锁 | IS 意向同享锁 |
X 排它锁 | 冲突 | 冲突 | 冲突 | 冲突 |
S 同享锁 | 冲突 | 兼容 | 冲突 | 兼容 |
IX 意向排它锁 | 冲突 | 冲突 | 兼容 | 兼容 |
IS 意向同享锁 | 冲突 | 兼容 | 兼容 | 兼容 |
解析:X和S的相互兼容关系step1描写过了,IX和IS的相互关系全部是兼容,这也很好理解,由于它们都只是“成心”,还处于YY阶段,没有真干,所以是可以兼容的;
剩下的就是X和IX,X和IS, S和IX, S和IS的关系了,我们可以由X和S的关系推导出这4组关系。
简单的说:X和IX的=X和X的关系。为何呢?由于事务在获得IX锁后,接下来就有权利获得X锁。如果X和IX兼容的话,就会出现两个事务都获得了X锁的情况,这与我们已知的X与X互斥是矛盾的,所以X与IX只能是互斥关系。其余的3组关系同理,可用一样的方式推导出来。
3,摹拟锁场景
在InnoDB Plugin之前,我们只能通过SHOW FULL PROCESSLIS和SHOW ENGINE INNODB STATUS来查看当前的http://www.wfuyu.com/db/要求,然后再判断事务中锁的情况。新版本的InnoDB Plugin中,在information_schema库中添加了3张表,INNODB_LOCKS、INNODB_TRX、INNODB_LOCK_WAITS。通过这3个表,可以更简单的监控当前的事务并且分析可能存在的锁问题。如果http://www.wfuyu.com/db/正常运行,这3个表都是空的,没有任何记录。
3.1,开启事务t1、t2,摹拟锁
开启2个session窗口,并且开启2个事务t1和t2。
在第1个窗口开启事务t1履行1个锁定操作,以下t1事务窗口界面:
mysql> set autocommit =0;
Query OK, 0 rows affected (0.00 sec)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
开始履行锁定操作
mysql> select * from test.t1 where a<5 for update;