【书 : InnoDB 存储引擎】第6 章 锁

6.1 什么是锁?

6.2 lock 和 latch

展示 lock 信息:

1 show engine innodb status

2 information_schema 表中的

innodb_trx, //  事务信息

innodb_locks, // 锁信息

innodb_lock_waits // 锁等待

连接三个表, 查询锁等待信息: 待补


6.3 InnoDB 引擎中的锁

6.3.1 锁的类型

共享锁(S Lock): 允许事务读一行数据

排他锁(X Lock): 允许事务删除或更新一行数据


意向锁的两种类型 --

意向共享锁(IS Lock): 事务想要获得一张表中某几行的共享锁

意向排他锁(IX Lock): 事务想要获得一张表中某几行的排他锁



6.3.2 一致性非锁定读

//演示的例子有问题

指 InnoDB 存储引擎通过多版本控制(Multi Version Concurrency Control, MVCC)的方式读取当前执行时间数据库中行的数据。//读取数据的快照

之所以称其为非锁定读, 因为不需要等待访问的行上 X 锁的释放。

在 InnoDB 存储引擎的默认设置下(REPEATABLE READ), 这是默认的读取方式。

在 READ COMMITTED (总读快照最新)和 REPEATABLE READ (读事务开始时的)下, InnoDB 引擎使用非锁定的一致性读


6.3.3 一致性锁定读

在某些情况下, 用户需要显示地对数据库读取操作进行加锁以保证数据逻辑的一致性。这要求数据库支持加锁语句, 即使是对于 select 的只读操作。

select ... for update  加了 X 锁, 其他事务不能对其加任何锁。

select ...  lock in share mode 加了 S 锁,其他事务只能对其加 S 锁, 若加 X 锁, 则会被阻塞。

以上两种加锁模式只能在一个事务中, 事务提交了, 锁也就被释放了。

6.3.4 自增长与锁


插入操作会依据自增长计数器(auto-increment counter)加 1 赋予自增长列, 这种实现方式称作Auto-Inc Locking

这种锁采用一种特殊的表锁机制, 为了提高插入的性能, 锁不是在一个事务完成后才释放, 而是在完成自增长值插入的 SQL 语句后立即释放。 // 可以车市下它的锁等待

innodb_autoinc_lock_mode ,控制自增长的模式, 该参数默认值为 1.

为 1 时: 对于 “simple inserts”, 该值会用互斥量(mutex)去对内存中的计数器进行累加的操作。对于“bulk inserts” 还是使用传统表锁的 auto-inc Locking 范式。需要注意的是, 如果已经使用 auto-inc locing 方式去产生自增长的值, 而这时需要再进行“simple inserts”的操作时, 还是需要等待 auto-inc locking 的释放。

6.3.5 外键和锁(待理解)

在 InnoDB 存储引擎中, 对于一个外键列, 如果梅雨显示地对这个列加索引, InnoDB 存储引擎自动对其加一个索引, 因为这样可以避免表锁。

对于外键值的插入或更新, 首先需要查询父表中的记录, 及 select 父表。 但对于父表的 select 操作, 不是使用一致性非锁定读的方式, 因为这样会发生数据不一致的问题, 因此使用的是 select ... lock in share mode 方式,即主动对父表加一个 S 锁,如果这时父表上已经加 X 锁, 自表上的操作会被阻塞。

两个 Session 中, 执行父表的 x 锁,未 commit 或 rollback 时,另一个 session 的修改操作会被阻塞;

6.4 锁的算法

6.4.1 行锁的 3 种算法

Record Lock : 单个行记录上的锁

Gap Lock : 间隙锁, 锁定一个范围, 但不含记录本身

Next-Key Lock:  Gap Lock + Record Lock , 锁定一个范围, 并且锁定记录本身



6.4.2 解决 Phantom Problem

两个事务中,由于一个事务的修改操作, 导致另一个事务的两次查询操作(一般为范围查询,如 select * from t where a> 2), 结果不唯一。

// 例子没有操作成功, 会话 2 的 插入操作不成功, 尽管 tx_isolation 已经设置 了 read-commited

如果用户通过索引查询一个值, 并对该行加一个 S Lock, 那么即使查询的值不在, 其锁定的也是一个范围, 因此若没有返回任何行, 那么新插入的值一定是唯一的。

6.5 锁的问题

6.5.1 脏读

一个事务可以读到另一个事务中未提交的数据。

脏页指的是在缓存池中已经修改的页, 但是还没有刷新到磁盘中, 即数据库实例内存中的页和磁盘中的页的数据是不一致的, 当然在刷新到磁盘之前, 日志已经被写入到了重做日志文件中。 脏读数据是指事务对缓冲池中行记录的修改, 并且还没有被提交。

脏读发生条件是需要事务的隔离级别为 READ UNCOMMITTED, 而目前绝大部分的数据库至少设置成 READ COMMITTED.

6.5.2 不可重复读

不可重复读和脏读的区别是:脏读是读到未提交的数据, 而不可重复读读到的是已经提交的数据, 但是违反了数据库的事务一致性要求。

这种问题被定义为 Phantom Problem , 即 幻读问题。

6.5.3 丢失更新

丢失更新时另一个锁导致的问题, 简单来说就是一个事务的更新操作会被另一个事务的更新操作锁覆盖, 导致数据不一致。


6.6 阻塞

// 例子没有成功, 插入时有锁生成。 select * from t where a<4 for update

// 4 是表里的最大值, 4 到正无穷, 均被锁了, 所以该表中均不可插入。

innodb_lock_wait_timeout 用来控制等待的时间, 默认是 50 秒。

默认情况下, innodb 不会回滚超时引发的错误异常。

6.7 死锁

6.7.1 死锁的概念

死锁是指两个或两个以上的事务在执行过程中, 因为争夺资源而造成的一种互相等待的现象。 若无外力作用, 事务都将无法推进下去。

解决死锁问题最简单的一种方法是超时。

当前数据库普遍采用 wait-for graph 的方式来进行死锁检测。

6.7.2 死锁的概率

系统中任何一个事务发生死锁的概率 约等于 n^2 * r^4 / 4 * R^2 

系统中事务的数量(n),数量越多发生死锁的概率越大。

每个事务操作的数量(r), 每个事务操作的数量越多, 发生死锁的概率越大。

操作事务的集合(R), 越小发生死锁概率越大。

注:每个操作从 R 行数据中取一条数据, 每行数据被取到的概率为 1 / R.

6.7.3 死锁的示例


InnoDB 存储引擎并不会回滚大部分的错误异常, 但是死锁除外。

InnoDB 引擎会自动对外键添加索引, 因而能够很好的避免死锁发生。 // 待理解

6.8 锁升级(待理解)

锁升级(Lock Escalation)是指将当前锁的粒度降低。如数据库把一个表的 1000 行锁升级为一个页锁, 或将页锁升级为表锁,来避免锁的开销。


InnoDB 引擎不存在锁的升级问题。 因为其不是根据每个记录来产生行锁的, 相反, 其根据每个事务访问的每个页对锁进行管理的, 采用位图的方式。 因此不管一个事务锁住一个记录还是多个记录, 其开销通常都是一致的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容