mysql 中的锁

一.锁的介绍

锁是计算机协调多个进程或线程并发访问某一资源的机制,在数据库中,除了传统的计算资源(cpu,ram,i/o)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性,有效性是所有数据库必须解决的一个问题。锁冲突也是影响数据库并发访问性能的一个重要因素。

二.mysql锁的分类

三.mysql中锁的介绍

mysql中的锁,按照锁的粒度分可以分为

  全局锁:锁定数据库中的所有表

                 3.1什么是全局锁

                  全局锁是针对整个数据库的锁。(我的理解就是一个数据库锁,锁的就是整个数据库)

                   全局锁里面又分为读锁和写锁。

                    读锁(共享锁):可以多个线程来读取数据,但是不可写入数据。

                    写锁(排他锁):不允许其他线程来读取和写入数据。

                  3.2 应用场景

                        dump表中所有数据的时候可以加入全局锁,保证数据的一致性。

                         利用mvcc机制也同样可以实现数据dump,但是不用加锁

                          

                   3.3 全局锁具体示例

                         开启读锁:flush tables with read lock;

                            开启读锁,其他线程不可以 修改操作,阻塞中或报错,查询可以

 

释放锁后可以修改成功

    

  表级锁:  每次操作锁住整张表。

                 3.1什么是表级锁

                      每次操作锁住整张表,开销小,加锁快,不会出现死锁,锁定的粒度大,发生锁冲突的概率最高,并发低。

                    表级锁里面又分为表共享读锁和表独占写锁。

                    表共享读锁  :{读锁(共享锁)}:可以多个线程来读取数据,但是不可写入数据。

                   表独占写锁   : {写锁(排他锁)}:不允许其他线程来读取和写入数据。

                  3.2 应用场景

                        1.读密集型的场景

                         2.写操作不是很密集的场景

                   3.3 表级锁具体演示

                          1.执行 alter table;

                          2.执行drop table 或者 truncate table;

                          3.lock tables t1 write,t2 read.

                             以上命令给表1加上写锁,给表2 加上读锁。

                              开启读锁的效果:

                              开启写锁

 

              查看 锁的状态:show open tables where in_use > 0;

              总结:

                       在同一个客户端中:

                       开启表的读锁,不可以进行修改,只可以查询

                       开启表的写锁,可以修改,可以查询

                       在不同的客户端中:

                       开启表的读锁,不可以进行修改,只可以查询

                       开启表的写锁,不可以修改,不可以查询 

                        开启表的写锁:下面是在不同的客户端中查询阻塞

                     

                       缺点:并发性能下降。

  行级锁:每次操作锁住对应的行数据。

                 3.1什么是行级锁

                      锁定的是数据的一行,粒度小,能提供更好的并发性,需要更多的资源。

                     行级锁里面又分为共享锁和排他锁。

                    共享锁 :{读锁(共享锁)}:可以多个线程来读取数据,但是不可写入数据。

                    排他锁 :{写锁(排他锁)}:不允许其他线程来读取和写入数据。

                 3.2使用场景

                     1.高并发

                     2.遇到事物的操作                     

                        查看那些是行级锁:select * from performance_schema.data_locks;

                        行级锁, 如果不在事物中执行,语句执行完毕,锁释放

                         

                        在事物中执行,在没有commit之前这个排他锁一直存在

                  案例演示:

                     执行排他锁(写锁):select ... for update  

                     第一个窗口开始事物,设置排他锁

                         第二个窗口可以查询,不可以修改

                         

                       执行共享锁(读锁):select......lock in share mode

                        第一个窗口开启 事物,开启共享锁

                           第二个窗口 可以查询,不可以修改

                      总结:  开启行的共享锁和排他锁不同窗口都可以读,不可以修改。

                     造成的问题:

                         1. 在多个事物当中会发生死锁(事物可以理解为多个线程)。

                         2.锁升级 (锁定多行后,发现还不如锁定整个表)

                         3.不同的事物隔离级别会影响锁的性能和行为,根据具体的场景来调整事物隔离级别。

按照锁的状态范围分类

 共享意向锁

 排他意向锁

意向锁个人理解就是一个“信号标记性能锁”,以前要去一行一行遍历表中的数据,判断是否存在行锁,现在去看一下,信号标记就可以。

概念 :意向锁是表锁,为了协调行锁和表锁的关系,支持多粒度(表锁与行锁)的锁并存。

作用:当有事物(线程)A有行锁时,mysql会自动为该表添加意向锁,事物(线程)b如果想申请整个表的写锁,那么不需要遍历每一行判断是否存在行锁,而直接判断是否存在意向锁,增强性能。

查看那些是行级锁:select * from performance_schema.data_locks;

案例演示:

  1.第一个窗口开启事物,并开启排他锁

          

2.查看当前的锁

查看LOCK_TYPE,LOCK_MODE 第一个是表级的意向排他锁 lX显示为排他锁

X是排他锁 LOCK_TYPE显示为 record 行级别。

3.在另一个窗口中添加写锁是阻塞状态:

总结:

间隙锁(范围锁)

和临界锁类似,是一个范围锁。两个值之间的空隙加锁。

演示示例:

1.查看当前的表结构

2.开启事物设置间隙锁(查询的id一定要不存在)

3.开启一个窗口,看到 id < 7的可以正常插入,id > 7 < 10的数据插入失败

临界锁

什么是临界锁 next-key 可以理解为一种特殊的间隙锁,也可以理解为一种特殊的算法。通过临界锁可以解决幻读的问题。每个数据行上的非唯一索引列上都会存在一把临界锁,当某个事物持有该数据的临界锁时,会锁住一段左开右闭区间的数据。innodb中行级锁是基于索引实现的,临界锁只与非唯一索引列有关,在唯一索引列上不存在临界锁。(把下面的演示做一遍才理解的更深刻)

演示案例

第一个窗口开启事物设置,设置临界锁为2000,表里面已经有1000的数据,

所以区间是1000-2000

第二个窗口在插入大于1000   小于 2000范围的数据是阻塞状态,插入不进去

发现插入小于1000也处于阻塞状态,拉拉了。一定要是 (每个数据行上的非唯一索引列上都会存在一把临界锁)才会有临界锁

mysql锁总结:

mysql中锁的分类可以多事物(线程)操作不可以多事物(线程)操作
数据库锁(全局锁)读锁写锁
表级锁

共享

lock tables t2 read.

排他

lock tables t1 write;

行级锁

共享锁 

select ..... lock in share mode;

排他锁

select..... for update;

                     共享锁 ,读锁 都可以理解为 共享读锁

                     排他锁 ,写锁  都可以理解为 排他写锁

                     间隙锁是innodb引擎为了解决幻读,临界锁也是为了解决幻读。

参考:阿里一面:MySQL锁你了解吗?说一下什么是mysql间隙锁?招架不住啊。。_哔哩哔哩_bilibili

  • 23
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值