MySQL锁机制漫谈(二)

MySQL锁机制漫谈(一)一文中,我们主要是探究了以下MySQL(主要是InnoDB)的锁的机制,但是我们平常经常使用的SQL语句一般都会加上什么锁,我自己也并不太熟悉,因此本文就罗列一些SQL语句在在执行过程中添加的锁情况。注意,本文主要是基于MySQL的官方文档而来,有不同意见也可以继续讨论。

一个UPDATE或者DELETE语句一般会在执行SQL操作的过程中对扫描到的每一个索引记录添加记录锁(record lock).InnoDB不会记录具体的where条件,而仅仅知道那些索引范围被扫描过。这些锁通常来说都是会阻塞在记录前面的间隙中插入数据的next-key lock。但是由于间隙锁可以被显式禁用,这同时会导致next-key锁定无法使用。

如果通过一个二级索引进行查询,同时该索引记录是独占的,InnoDB会找到对应的聚集索引并加锁。

如果你的表中没有适合SQL语句的索引,此时MySQL就会扫描整个表来执行语句,因此表中的每一行就被锁住了,这回导致任何其他事物的insert操作都会被阻塞。所以,好的索引能够极大的减少不必要的行扫描。

对于SELECT ... FOR UPDATE或者 SELECT ... LOCK IN SHARE MODE来说,锁被你获取是进行行扫描,而且会在对比发现呢不符合结果集(也即不符合WHERE后的条件)而被释放。但是在某些情况下,由于结果集和数据源之间的关系在查询过程丢失,行锁可能不会立即被释放(如在一个UNION操作中,在没有评估这些行是否符合结果集前,被扫描的行可能会插入一个临时表中。在这种情况下,临时表和原始表中的行的关系就丢失了,后续的行锁不会立即释放知道整个查询的结束)。

InnoDB在执行SQL语句时会添加如下类型的锁:

  • SELECT ... FROM 这是一个一致性读,会读取数据库的一个快照版本同时不会加锁(即所谓的一致性非锁定读),但这不会发生在数据库的隔离级别设置为SERIALIZABLE。在SERIALIZABLE隔离级别下,每个查询会在每一个扫描到的索引上添加共享的next-key锁。但是,对于使用唯一索引来查询唯一行的语句来说,此时只会加上record lock。

  • SELECT ... FROM ... LOCK IN SHARE MODE 该语句会在查询时每一个扫描到的索引上添加共享的next-key锁。但是,对于使用唯一索引来查询唯一行的语句来说,此时只会加上record lock。

  • SELECT ... FROM ... FOR UPDATE 该语句会在查询时每一个扫描到的索引上添加排他的next-key锁。但是,对于使用唯一索引来查询唯一行的语句来说,此时只会加上record lock。对于碰到的索引记录,该语句会通过执行SELECT ... FROM ... LOCK IN SHARE MODE 或者在特定的隔离级别上读来阻塞其他事务。一致性读会忽略读视图中的任何加在记录上的锁。

  • UPDATE ... WHERE 该语句会在查询时每一个扫描到的索引上添加排他的next-key锁。但是,对于使用唯一索引来查询唯一行的语句来说,此时只会加上record lock。当UPDATE操作修改一个聚集索引记录时,隐式的锁会影响二级索引。UPDATE操作会在一个二级索引上加上共享锁当在插入一个二级索引记录之前执行重复检查扫描或者当进行插入一个二级索引记录时。

  • DELETE ... FROM ... WHERE 该语句会在查询时每一个扫描到的索引上添加排他的next-key锁。但是,对于使用唯一索引来查询唯一行的语句来说,此时只会加上record lock。

  • INSERT 操作在插入行上加上了排他锁,这是一个基于索引的锁,而非next-key lock (也即不是间隙锁,因此也就不会阻止其他事务在要插入的行前面执行插入语句)。

在插入该行记录前,会加一种叫做插入意向间隙锁的gap lock。该锁是这样告知一个事务有插入的意向的-即如果多个事务在同一个索引间隙上执行插入操作,如果各事务不是在同一个插入点上进行掺入操作就不需要互相等待。假设现有值为4和7的索引记录,分别有两个事务尝试插入值5和6,这两个事务都会先去获取插入意向锁而非在被插入的行上获取排他锁去锁住4和7之间的间隙,由于这两行的插入也不存在冲突,故也不会去互相阻塞。

如果出现了key重复的错误,就会在该重复key索引记录上加上共享锁。如果多个事务尝试在同一个行记录上进行插入同时某个事务已经在该行上拥有一个排他锁,那么这种共享锁就会导致死锁的出现。

假设一个场景,一个InnoDB表t1有如下结构:

CREATE TABLE t1 (i INT, PRIMARY KEY (i)) ENGINE = InnoDB;

现在假设有三个事务按顺序在执行以下操作,
事务1:

START TRANSACTION;
INSERT INTO t1 VALUES(1);

事务2:

START TRANSACTION;
INSERT INTO t1 VALUES(1);

事务3:

START TRANSACTION;
INSERT INTO t1 VALUES(1);

事务1:

ROLLBACK;

事务1的第一个操作会获取一个排他锁;事务2和事务3的操作会导致主键重复错误,同时两者都会请求获取一个共享锁在该行。当事务1进行回滚,会释放在该行上的排他锁,同时事务2和事务3的排队的共享锁请求会成功。在这个点,事务2和事务3会形成死锁。没有一方会获取该行的排他锁由于各自都持有共享锁。

  • INSERT...ON DUPLICATE KEY UPDATE 该操作与简单的INSERT操作不同。当发生key重复错误,该操作会在要更新的行上加上排他锁而非共享锁。而对重复主键值这是一个排他索引记录锁;对重复的唯一键值,这回事一个排他next-key锁。

  • INSERT INTO T SELECT...FROM S WHERE ... 该操作会在要插入的表T的每一行加上排他索引记录锁。如果表的事务隔离模型是READ_COMMITTED或innodb_locks_unsafe_for_binlog始能同时手误隔离级别不是SERIALIZZABLE,InnoDB会在表S上进行一致性读(无锁)。否则,InnoDB会在表S上的行加上共享next-key锁。

参考

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

推荐阅读更多精彩内容

  • MySQL技术内幕:InnoDB存储引擎(第2版) 姜承尧 第1章 MySQL体系结构和存储引擎 >> 在上述例子...
    沉默剑士阅读 7,304评论 0 16
  • 当一个系统访问量上来的时候,不只是数据库性能瓶颈问题了,数据库数据安全也会浮现,这时候合理使用数据库锁机制就显得异...
    初来的雨天阅读 3,499评论 0 22
  • 概述 数据库锁定机制简单来说,就是数据库为了保证数据的一致性,而使各种共享资源在被并发访问变得有序所设计的一种规则...
    datazhen阅读 737评论 0 2
  • 今夫下午我和我的朋友和我老姨去万家惠水上乐园玩, 我们一去那儿就兴备的不得了[呲牙]因为那儿特别好玩儿。 我们先换...
    梓悦妈妈1阅读 123评论 0 1
  • 哈喽大家好我是骆长珊今天是2017年12月21日,今天是我每天一篇文章的第二十七篇。 宇宙就是一座黑暗森林,每个文...
    骆长珊阅读 209评论 0 0