锁是计算机协调多个进程或线程并发访问某一资源的机制,应该都不陌生。?但在这之前我们先来看看并发控制,理清MVCC多版本并发控制和锁的关系,这也是之前我很迷惑的一个点
在数据库中,数据可以允许多个用户同时访问,因此在并发场景下需要确保数据的一致性,可以简单梳理一下,并发场景有三种:
从宽泛意义上讲,目前有三种并发控制技术:
对并发控制有了一定的了解,但需要注意:
再总结一下:
MySQL中锁大致可以按照数据库的层级分为DB级别锁、表级别锁以及行级别锁,而不同的数据库引擎支持的锁类型也不同:
在DB级别对整个数据库实例加锁,加锁之后:
加锁方式:lock Flush tables with read lock
释放锁:unlock tables(发生异常时会自动释放)
全局锁主要用于做全库的逻辑备份,和设置数据库只读(set global readonly=true)相比,全局锁在发生异常时会自动释放
表级别对操作的整张表加锁,锁定颗粒度大,资源消耗少,不会出现死锁,但并发度低,表级锁有两种模式:
MyISAM引擎默认支持表级别锁
表级别的锁有两种:表锁和元数据锁(MDL)
显示加锁方式:lock tables {tb_name} read/write
释放锁:unlock table {tb_name} (连接中断也会自动释放)
MyISAM引擎下隐式加锁:
隐式锁,主要针对对表结构改变的操作(DDL),没有显示加锁方式,访问表时自动加锁:
到这里你是不是会有疑问:假设我要向表里增加一个字段隐式加MDL写锁,那么线上所有对这个表的增删改查(DML)操作都会阻塞
查看表级锁争用情况:SHOW STATUS LIKE ‘table%’
总之表级锁因为锁的粒度大,若一个事物执行时间过长,很可能会导致后面对这个表的请求全部阻塞
InnoDB支持行级别锁,锁粒度小并发度高,但是加锁开销大也很可能会出现死锁,锁模式:
InnoDB的默认隔离级别RR(可重复读),在RR下读数据有两种方式:
加锁方式:
解锁:
提交/回滚事物(commit/rollback)
kill 阻塞进程
注:以下行级锁分析都默认RR(可重复读)的事物隔离级别
InnoDB的行锁是通过给索引上的索引项加锁来实现的
可以看下面例子,涉及到回表对聚簇索引的索引项也会加锁:
举个例子更好理解:
现在你可能已经知道了:
如果在加Record Lock的基础之上再加上Gap Lock问题就解决了
通过上面这个例子,我们可以看到:
行级锁默认加 next-key lock,查询过程中访问到的索引项都会加锁,而根据不同的索引也有不同的加锁规则:
注:以上加锁规则参考《mysql 45讲》和实践验证自己总结所得,非官方规则
可能有点难理解,针对这几种情况分别举例说明一下,假设我有以下数据:
id | name | age |
---|---|---|
1 | 张三 | 21 |
4 | 王一 | 26 |
6 | 小军 | 18 |
9 | 小红 | 23 |
在上面的数据表我们可以得到5个next-key lock 区间:
唯一索引(id):(-∞,1],(1,4],(4,6],(6,9] ,(9,+supremum]
非唯一索引(age):(-∞,18],(18,21],(21,23],(23,26] ,(26,+supremum]
唯一索引等值查询:
唯一索引范围查询:
非唯一索引等值查询:
非唯一索引范围查询:
细心一点你会发现上面例子中:
如果上面例子中非唯一索引的查询用的是 select … for update,还需要分析聚簇索引(主键索引)的加锁情况
死锁指的是两个或两个以上的事物在执行过程中争抢锁资源而造成相互等待的情况
表锁不会出现死锁,主要还是针对InooDB的行锁,可以看下面的例子:
# 查询InnoDB锁的整体情况
# 可以重点查看Innodb_row_lock_waits和Innodb_row_lock_time_avg这两个值
# 如果数值较大,说明锁之间的竞争大
show status like 'innodb_row_lock%';
#可以通过INNODB_TRX、INNODB_LOCKS、INNODB_LOCK_WAITS这三个表
#分析可能存在的锁的问题
select * from information_schema.INNODB_TRX; # 查看所有事物
select * from information_schema.INNODB_LOCKS; # 查看锁
select * from information_schema.INNODB_LOCK_WAITS; # 查看锁等待
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/qq_43842093/article/details/121964123
内容来源于网络,如有侵权,请联系作者删除!