MySQL中的锁机制

目录

MySQL中的锁机制是什么?

MySQL中锁的分类

表锁~~~

给表加读锁

给表加写锁

MyISAM引擎中表锁的特点

MyISAM引擎中分析表锁

行锁~~~

行锁的举例

索引失效对行锁的影响

间隙锁的危害

如何锁定一行

InnoDB引擎中行锁的特点

InnoDB引擎中分析行锁 

页锁~~~ (了解即可)


 

MySQL中的锁机制是什么?

 

锁是计算机协调多个进程或线程并发访问某一资源的机制。

在数据库中,除传统的计算机资源(CPU、RAM、IO)的争用之外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是数据库必须解决的一个问题。锁冲突也是影响数据库并发访问性能的一个重要因素,因此锁对于数据库而言尤为重要,也更加复杂
 

 

MySQL中锁的分类

 

  • 从数据操作类型分 

读锁(共享锁) :针对同一份数据,多个读操作可以同时进行而不会相互影响

写锁(排它锁) :当前写操作没有完成前,它会阻断其他写锁和读锁。

  • 从对数据操作的颗粒度分

表锁:偏向MyISAM存储引擎,开销小,加锁快,无死锁,锁定粒度大,发送锁冲突的概率最高,并发最低。

行锁:偏向InnoDB存储引擎,开销大,加锁慢,会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高

 

 

表锁~~~

给表加读锁

 

MySQL中的锁机制_第1张图片 

 

 

给表加写锁

 

MySQL中的锁机制_第2张图片 

 

 

MyISAM引擎中表锁的特点

 

MyISAM引擎在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执行增删改操作前会自动给涉及的表加写锁

MySQL的表锁有两种模式

  • 表共享读锁(Table Read Lock)
  • 表独占写锁(Table Write Lock)

 

结论:

1.对MyISAM表的读操作(加读锁)不会阻塞其他进程对同一表的读请求,但会阻塞对同一表的写请求。只有当读锁释放,才会执行其他进行的写操作

2.对MyISAM表的写操作(加写锁)会阻塞其他进程对同一表的读和写操作,只有当写锁释放后,才会执行其他进程的读写操作

简言之,读锁会阻塞写,但不会阻塞读。写锁会把读和写都阻塞 

 

 

MyISAM引擎中分析表锁

 

 [查看哪些表被加锁了]

show open tables;

[根据参数分析表锁]

show status like 'table%';

Table_locks_immediate:产生表锁的次数

Table_locks_waited:出现表锁后发生的等待和阻塞次数(重要参数) 

MySQL中的锁机制_第3张图片

[MyISAM引擎的读写锁调度特点]

MyISAM的读写锁调用是写优先,这也是MyISAM不适合做写为主表引擎的原因。因为写锁后,其他线程不能做任何操作,大量的更新会使查询很难得到锁,造成永远阻塞。

 

 

行锁~~~

行锁的举例

 

演示行锁之前必须先把mysql的commit事务自动提交关闭,为什么?想想你发一个朋友圈是不是你自己先看到,然后你的朋友才看到呢?如果要保证你发的所有消息都是和朋友同一时间看到,这样的话对数据库的性能要求太高,因为这种操作是让所有事务都停下来专门为你干事,同志们想想如果每一件事情都让其他事务马上停下来,是不是违背了高可用性(高可用性的目的是减少停工时间)?

因此我们停止事务自动提交,模拟成当一个数据发送一段时间后其他用户才能查看,这样更符合现实中的情况~

我们知道,每个对SQL语句的操作都自动应用了行锁。在手动提交事务的前提下,A用户更新id为4的记录,在A用户没输入commit之前,B用户是看不到A更新后的数据的。

 

 

索引失效对行锁的影响

 

之前我们讲过,当索引失效时,sql的性能会下降,但更严重的是索引失效时,行锁会变成表锁。

假如你更新的varchar字段没写' ',在事务没提交完成之前,行锁会立马变成表锁。 在事务没提交之前,不论是你操作同一行记录或者不是同一行记录,都会进入阻塞状态, 直到事务提交。

 

 

间隙锁的危害

 

什么是间隙锁

当我们用范围条件而不是相等条件检索数据,并请求共享或排它锁时,InnoDB会给符合条件的已有数据记录的索引项加锁,对于键值在条件范围内但并不存在的记录叫做间隙。即id有1,3,4。你的条件是<4并且>1,他会自动把2和3都加锁,即使没有id为2

MySQL中的锁机制_第4张图片

间隙锁的危害

可能会造成阻塞,对性能有很大影响。例如在操作<4并且>1时,这时候你新增id为2的记录,新增的操作就会阻塞,直到第一条条事务提交完成 

 

 

如何锁定一行

 

SQL语句后面加上一个for update即可

MySQL中的锁机制_第5张图片 

 

InnoDB引擎中行锁的特点

 MySQL中的锁机制_第6张图片

 

InnoDB引擎中分析行锁 

 

MySQL中的锁机制_第7张图片 

 

页锁~~~ (了解即可)

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

你可能感兴趣的:([MySQL])