mysql表锁行锁页锁各种锁

MySQL锁

1.锁知识点脑图

01.png

2.锁种类释义

2.1锁概述

锁是计算机协调多个进程或线程并发访问某一资源的机制。锁保证数据并发访问的一致性、有效性;锁冲突也是影响数据库并发访问性能的一个重要因素。锁是Mysql在服务器层和存储引擎层的的并发控制。

加锁是消耗资源的,锁的各种操作,包括获得锁、检测锁是否是否已解除、释放锁等。

2.2粒度划分锁

粒度:mysql中代指锁的级别

表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低对整张表加锁。

行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。

2.3使用方式

共享锁:是一种读锁,当前事务加锁后其他事务可以读但不可以写.存储引擎不同实现的功能也不一样.

排他锁:是一种写锁,当前事务加锁后其他事务不可以读也不可以写.存储引擎不同实现的功能也不一样.

2.3逻辑划分

悲观锁和乐观锁是在很多框架都存在的一种思想,不要狭义地认为它们是某一种框架的锁机制

乐观锁:乐观锁需要程序员自己去实现的锁机制

悲观锁:悲观锁的实现是基于Mysql自身的锁机制实现

2.4各存储引擎对锁的支持

MyISAM 和 MEMORY 存储引擎采用的是表级锁(table-level locking)

BDB 存储引擎采用的是页面锁(page-level locking),但也支持表级锁

InnoDB 存储引擎既支持行级锁(row-level locking),也支持表级锁,但默认情况下是采用行级锁。

3.MyISAM锁

3.1支持的粒度锁

MyISAM中默认支持的表级锁有两种:即[共享读锁][独占写锁]。表级锁在MyISAM和InnoDB的存储引擎中都支持,但是InnoDB默认支持的是行锁。

3.2锁的使用方式

独占写锁:当一个线程获取到表级写锁后,只能由该线程对表进行读写操作,别的线程必须等待该线程释放锁以后才能操作

共享读锁:****当一个线程获取到表级读锁后,该线程只能读取数据不能修改数据,其它线程也只能加读锁,不能加写锁

3.3锁竞争查看方法

MyISAM存储引擎中,可以通过查询变量来查看并发场景锁的争夺情况,具体执行下面的sql语句:

show status like 'table%';

02.png

主要是查看table_locks_waitedtable_locks_immediate的值的大小分析锁的竞争情况。

Table_locks_immediate:表示能够立即获得表级锁的锁请求次数;Table_locks_waited表示不能立即获取表级锁而需要等待的锁请求次数分析,「值越大竞争就越严重」

3.4并行插入

解锁和释放锁都是Mysql底层隐式的执行的

在我们平时执行select语句的时候就会隐式的加读锁,执行增、删、改的操作时就会隐式的执行加写锁。

MyISAM存储引擎中,虽然读写操作是串行化的,但是它也支持并发插入,这个需要设置内部变量concurrent_insert的值。

它的值有三个值0、1、2。可以通过以下的sql查看concurrent_insert的默认值为「AUTO(或者1)」

concurrent_insert的值为NEVER (or 0)表示不支持比并发插入;值为AUTO(或者1)表示在MyISAM表中没有被删除的行,运行另一个线程从表尾插入数据;值为ALWAYS (or 2)表示不管是否有删除的行,都允许在表尾插入数据。

3.5锁调度

MyISAM存储引擎中,「假如同时一个读请求,一个写请求过来的话,它会优先处理写请求」,因为MyISAM存储引擎中认为写请求比都请求重要。

这样就会导致,「假如大量的读写请求过来,就会导致读请求长时间的等待,或者"线程饿死",因此MyISAM不适合运用于大量读写操作的场景」,这样会导致长时间读取不到用户数据,用户体验感极差。

当然可以通过设置low-priority-updates参数,设置请求链接的优先级,使得Mysql优先处理读请求。

4.InnoDB锁

4.1支持的粒度锁

行锁是InnoDB默认的支持的锁机制MyISAM不支持行锁,这个也是InnoDB和MyISAM的区别之一。另外innoDB支持事务,MyISAM不支持事务.

InnoDB中除了有「表锁」「行级锁」的概念,还有Gap Lock(间隙锁)、Next-key Lock锁,「间隙锁主要用于范围查询的时候,锁住查询的范围,并且间隙锁也是解决幻读的方案」

InnoDB中的行级锁是「对索引加的锁,在不通过索引查询数据的时候,InnoDB就会使用表锁」

4.2使用方式

InnoDB的行锁也是分为行级「共享读锁(S锁)「和」排它写锁(X锁)」,原理特点和MyISAM的表级锁两种模式是一样的。

执行非索引条件查询执行的是表锁。

执行索引查询是否是加行锁,还得看Mysql的执行计划,可以通过explain关键字来查看。

用普通键索引的查询,遇到索引值相同的,也会对其他的操作数据行的产生影响。

4.3InnoDB间隙锁

当我们使用范围条件查询而不是等值条件查询的时候,InnoDB就会给符合条件的范围索引加锁,在条件范围内并不存的记录就叫做"间隙(GAP)"

大家大概都知道在事务的四大隔离级别中,不可重复读会产生幻读的现象,只能通过提高隔离级别到串行化来解决幻读现象。

但是Mysql中的不可重复是已经解决了幻读问题,它通过引入间隙锁的实现来解决幻读,通过给符合条件的间隙加锁,防止再次查询的时候出现新数据产生幻读的问题。

4.4死锁

死锁在InnoDB中才会出现死锁,MyISAM是不会出现死锁,因为MyISAM支持的是表锁,一次性获取了所有得锁,其它的线程只能排队等候。

而InnoDB默认支持行锁,获取锁是分步的,并不是一次性获取所有得锁,因此在锁竞争的时候就会出现死锁的情况。

虽然InnoDB会出现死锁,但是并不影响InnoDB最受欢成为迎的存储引擎,MyISAM可以理解为串行化操作,读写有序,因此支持的并发性能低下。

  • 死锁案例

当前有表如下:


03.png

其中name="spike"的有两条数据,并且name字段为普通索引,分别是id=3和id=4的数据行,现在假设有两个事务分别执行下面的两条sql语句:

// session1
update user_info set age = 19 where name ='spike';
// session2执行
select * from user_info where id = 3 or id = 4;

其中session1执行的sql获取的数据行是两条数据,假设先获取到第一个id=3的数据行,然后cpu的时间分配给了另一个事务,另一个事务执行查询操作获取了第三行数据也就是id=3的数据行。

当事务2继续执行的时候获取到id=3的数据行,锁定了id=3的数据行,此时cpu又将时间分配给了第一个事务,第一个事务执行准备获取第二行数据的锁,发现已经被其他事务获取了,它就处于等待的状态。

当cpu把时间有分配给了第二个事务,第二个事务准备获取第一行数据的锁发现已经被第一个事务获取了锁,这样就行了死锁,两个事务彼此之间相互等待。

4.5死锁解决方案

首先要解决死锁问题,在程序的设计上,当发现程序有高并发的访问某一个表时,尽量对该表的执行操作串行化,或者锁升级,一次性获取所有的锁资源。

然后也可以设置参数innodb_lock_wait_timeout,超时时间,并且将参数innodb_deadlock_detect 打开,当发现死锁的时候,自动回滚其中的某一个事务。

5.总结

上面详细的介绍了MyISAM和InnoDB两种存储引擎的锁机制的实现,并进行了测试。

MyISAM的表锁分为两种模式:「共享读锁」「排它写锁」。获取的读锁的线程对该数据行只能读,不能修改,其它线程也只能对该数据行加读锁。

获取到写锁的线程对该数据行既能读也能写,对其他线程对该数据行的读写具有排它性。

MyISAM中默认写优先于去操作,因此MyISAM一般不适合运用于大量读写操作的程序中。

InnoDB的行锁虽然会出现死锁的可能,但是InnoDB的支持的并发性能比MyISAM好,行锁的粒度最小,一定的方法和措施可以解决死锁的发生,极大的发挥InnoDB的性能。

InnoDB中引入了间隙锁的概念来决解出现幻读的问题,也引入事务的特性,通过事务的四种隔离级别,来降低锁冲突,提高并发性能。

6.参考文档

本文参考文档[大厂面试官必问的Mysql锁机制] (https://zhuanlan.zhihu.com/p/150101667),大哥文档比较详细我这里是按自己理解做的笔记

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

推荐阅读更多精彩内容