InnoDB 存储引擎的锁机制
测试环境隔离级别:REPEATABLE-READ
行级别的 - Share and Exclusive Locks
- 共享锁 S:允许持有S锁的事务对行进行读操作
- 排他锁 X: 允许持有X锁的事务对行进行update或delete操作
表级别的意向锁 - Intention Lock
InnoDB支持多粒度的锁定,允许行锁和表锁共存。通过意向锁来实现。
比如,SELECT ... LOCK IN SHARE MODE sets an IS lock and SELECT ... FOR UPDATE sets an IX lock.
- 意向共享锁(IS):在对数据行获取S锁之前,必须先获取IS锁或更强级别的锁
- 意向排他锁(IX):在对数据行获取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 |
A lock is granted to a requesting transaction if it is compatible with existing locks, but not if it conflicts with existing locks.
A transaction waits until the conflicting existing lock is released. If a lock request conflicts with an existing lock and cannotbe granted because it would cause deadlock, an error occurs.
因此,除了对整个表的请求(比如,LOCK TABLES ... WRITE)外,意向锁不会阻塞其他的事务。持有意向锁表示持有者正在锁定数据行,或者即将锁定数据行。
deadlock:
A deadlock can occur when the transactions lock rows in multiple tables (through statements such as UPDATE or SELECT ... FOR UPDATE), but in the opposite order. A deadlock can also occur when such statements lock ranges of index records and gaps, with each transaction acquiring some locks but not others due to a timing issue.
索引记录上的锁 - Record Lock
比如,SELECT c1 FOR UPDATE FROM t WHERE c1 = 10;避免其他的事务在t.c1=10的位置进行insert、update和delete操作
record lock始终锁定索引记录,即使一个表没有进行索引定义,对于这种情况,InnoDB创建一个隐藏的聚集索引并使用该索引记录锁定
Cap Lock
比如,SELECT c1 FOR UPDATE FROM t WHERE c1 BETWEEN 10 and 20;会在t.c1在10到20之间的索引记录上加锁,防止其他的事务在t.c1列上插入10到20之间的值
测试:t2.id上无索引
mysql> select * from t2;
+------+
| id |
+------+
| 1 |
| 5 |
| 8 |
| 11 |
+------+
4 rows in set (0.00 sec)
S1 S2
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> begin;
mysql> update t2 set id=6 where id=5; Query OK, 0 rows affected (0.00 sec)
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0 mysql> insert into t2 values(5);
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> insert into t2 values(1);
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> insert into t2 values(8);
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> insert into t2 values(6);
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
S1锁住整张表
t2.id上加上索引的验证
mysql> alter table t2 add index id_idx(id);
Query OK, 0 rows affected (0.54 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> begin;
mysql> update t2 set id=6 where id=5; Query OK, 0 rows affected (0.00 sec)
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0 mysql> insert into t2 values(8);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t2 values(7);
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> insert into t2 values(1);
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
S1会在[1,5] [5,8)区间加上间隙锁
Next-Key Locks
A next-key lock is a combination of a record lock on the index record and a gap lock on the gap before the index record.
InnoDB uses next-key locks for searches and index scans, which prevents phantom rows .
幻影读的解释:http://dev.mysql.com/doc/refman/5.6/en/innodb-next-key-locking.html
验证如上:S1会在id=5的行加上X锁,为防止幻读,又在5的左边[1,5) 和5的又边(5,8)加上了gap锁
Insert Intention Locks
是gap锁的一种。多个事务如果不是在相同的索引范围内插入,则无需等待彼此
测试:
mysql> select * from t2;
+------+
| id |
+------+
| 1 |
| 5 |
| 8 |
| 11 |
+------+
会话S1 会话S2
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into t2(id) values(7); mysql> begin;
Query OK, 1 row affected (0.00 sec) Query OK, 0 rows affected (0.00 sec)
mysql> insert into t2(id) values(6);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t2(id) values(7);
Query OK, 1 row affected (0.00 sec)
两个会话在插入的行上获取排他锁前,分别在id为5~8的行记录范围内持有intention locks,但不会阻塞对方,因为行之间没有冲突。
再举一个会话在要插入的行记录上获取排他锁之前获取insert intention lock但被阻塞的例子:
S1在id>5的行持有排它锁。此排它锁包含5~11之间的gap锁
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from t2 where id>5 for update;
+------+
| id |
+------+
| 8 |
| 11 |
+------+
S2上在S1查询出的行范围内插入行记录。会持有insert intention lock,但是会等待排它锁
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into t2 values(7);
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
参考链接:
http://dev.mysql.com/doc/refman/5.6/en/innodb-locking.html
http://www.hollischuang.com/archives/923
InnoDB 存储引擎的锁机制的更多相关文章
- InnoDB存储引擎的锁
InnoDB存储引擎的锁 锁的类型 锁的类型包括: 1. 共享锁(S lock),允许事务读取一行数据 2. 排他锁(X lock),允许事务删除或更新一行数据 锁的兼容性a X S ...
- 图文实例解析,InnoDB 存储引擎中行锁的三种算法
前文提到,对于 InnoDB 来说,随时都可以加锁(关于加锁的 SQL 语句这里就不说了,忘记的小伙伴可以翻一下上篇文章),但是并非随时都可以解锁.具体来说,InnoDB 采用的是两阶段锁定协议(tw ...
- Mysql存储引擎以及锁机制
一.常用命令 1.查看引擎(默认为InnoDB) 查看mysql提供的存储引擎:show engienes 查看mysql当前默认的存储引擎:show variables like '%storage ...
- 《Mysql技术内幕,Innodb存储引擎》——锁
lock与latch 在数据库中lock与latch分别指不同的所. latch:可分为互斥量(mutex)和读写锁(rwlock),目的在于保证数据库内部的结构中共享资源并发时能够正确操作,其对象主 ...
- Galera集群server.cnf参数调整--Innodb存储引擎内存相关参数(一)
在innodb引擎中,内存的组成主要有三部分:缓冲池(buffer pool),重做日志缓存(redo log buffer),额外的内存池(additional memory pool).
- MySQL内核:InnoDB存储引擎 卷1
MySQL内核:InnoDB存储引擎卷1(MySQL领域Oracle ACE专家力作,众多MySQL Oracle ACE力捧,深入MySQL数据库内核源码分析,InnoDB内核开发与优化必备宝典) ...
- 1009MySQL数据库InnoDB存储引擎Log漫游
00 – Undo Log Undo Log 是为了实现事务的原子性,在MySQL数据库InnoDB存储引擎中,还用Undo Log来实现多版本并发控制(简称:MVCC). - 事务的原子性(Atom ...
- MySQL InnoDB存储引擎undo redo解析
本文介绍MySQL数据库InnoDB存储引擎重做日志漫游 00 – Undo Log Undo Log 为了实现事务原子,在MySQL数据库InnoDB存储引擎,还使用Undo Log(简称:MVCC ...
- InnoDB存储引擎介绍-(2)redo和undo学习
01 – Undo LogUndo Log 是为了实现事务的原子性,在MySQL数据库InnoDB存储引擎中,还用Undo Log来实现多版本并发控制(简称:MVCC). - 事务的原子性(Atomi ...
随机推荐
- Could not create the view: An unexpected exception was thrown.
今天打开Myeclipse10的时候,发现server窗口出现一堆问题,问题如标题,然后下方出现了一堆java.lang.NullPointerException的问题. java.lang.Null ...
- MongoDB使用锦集
查询集合中记录数量:db.collection.count()
- 数据库DDL审计
一.为什么需要数据库DDL审计? DDL在生产系统中扮演非常重要的作用. 1)首先从业务角度来说,DDL可能意味着表结构变更,意味着新的版本即将发布,是个重要的时刻. 2)其次从运维角度来说,DDL尤 ...
- 配置sublime text 3 的Python开发环境
为了在sublime实现像Python自带idle一样的F5交互功能: 首先安装package control然后install Sublime REPL:然后配置 Preference-->P ...
- 《开源安全运维平台:OSSIM最佳实践》内容简介
<开源安全运维平台:OSSIM最佳实践 > 李晨光 著 清华大学出版社出版 内 容 简 介在传统的异构网络环境中,运维人员往往利用各种复杂的监管工具来管理网络,由于缺乏一种集成安全运维平台 ...
- linux 挂载光盘:mount: you must specify the filesystem type
尝试挂载光盘镜像时出现mount: you must specify the filesystem type 使用-t auto -t iso9660 或不加参数都搞不定,最后在以下链接找到解决办法: ...
- 【自动化学习笔记】_环境搭建Selenium2+Eclipse+Java+TestNG_(一)
目录 第一步 安装JDK 第二步 下载Eclipse 第三步 在Eclipse中安装TestNG 第四步 下载Selenium IDE.SeleniumRC.IEDriverServer 第五步 下 ...
- Python--逆序打印
才开始学习Python,我个人喜欢边看实例边学习其中的知识点,于是在网上找到了“Python100例”, 案例很不错,但是其中有几个例子不能正确实现,比如第29个例子--“给一个不多于5位的正整数, ...
- android事件拦截处理机制详解
前段时间刚接触过Android手机开发,对它的事件传播机制不是很了解,虽然网上也查了相关的资料,但是总觉得理解模模糊糊,似是而非,于是自己就写个小demo测试了一下.总算搞明白了它的具体机制.写下自己 ...
- java map的默认排序问题
import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import java.util.Tre ...