首页 > 数据库 >Mysql锁机制浅谈一

Mysql锁机制浅谈一

时间:2024-10-10 11:17:55浏览次数:3  
标签:事务 加锁 浅谈 间隙 记录 索引 意向锁 Mysql 机制

mysql是如何加锁的?

加锁默认是加临键锁,有特殊情况会优化为其他锁

索引上的等值查询

  • 唯一索引,给不存在的记录加锁时,优化为间隙锁
  • 普通索引,向右遍历至最后一个不满足查询条件的值时吗退化为间隙锁

索引上的范围查询

  • 唯一索引:访问到不满足条件的第一个值为止

主键索引

ps:如果是非主键的唯一索引,那么会在大于等于时不会退化为记录锁,并且还会给主键索引加上记录锁

等值查询

image-20241007105137298

范围查询

大于

image-20240921141644217

大于等于

image-20240921141704613

小于或小于等于

image-20240910220350061

非唯一索引

等值查询

image-20240910222723978

范围查询

image-20240910222745401

MySQL的锁机制

在一次事务中加的所有锁,会在事务结束时一起释放。

MySQL中的锁

根据锁的粒度可以划分为:

  • 【全局锁】锁定数据库中的所有表,使其处于只读状态,常用在需要数据备份时
  • 【表级锁】
    1. 【表锁】锁住整张表,粒度较大
    2. 【元数据锁】防止DML和DDL冲突所加的隐式锁
    3. 【意向锁】为避免加表锁时逐行查看行级锁的加锁情况这样的低效操作而加的隐式锁
  • 【行级锁】
    1. 【记录锁】对表中的单条记录加锁。在读已提交和可重复读的事务隔离级别下都支持。
    2. 【间隙锁】对记录与记录之间的间隙加锁。只在可重复读的事务隔离级别下支持。间隙锁是开区间
    3. 【临键锁】对记录以及它与上一条记录之间间隙加的锁。临键锁是左开右闭区间

根据锁的容斥性,还可以分为共享锁S独占锁X

根据锁的思想,还可以分为悲观锁乐观锁

当前读快照读

  • 【当前读】当前读中执行的sql语句都会加锁

    下面四类语句是会加独占锁X的:

    1. select ... from ... for update
    2. insert ...
    3. update ...
    4. delete ...
  • 【快照读】和MVCC相关,不加锁

读锁和写锁的兼容性问题

【读锁】不排斥读锁,排斥写锁

【写锁】对读和写都排斥

注意,间隙锁锁定的是 索引记录之间的“间隙”,而不是锁定具体的记录。它的目的是防止其他事务在锁定的间隙中插入新的记录,从而避免 幻读。所以临键锁和间隙锁是可以同时存在的。

比如这里有两个事务查询:

事务A:

select * from easyjavademo.user where id = 5 for update;

事务B:

select * from easyjavademo.user where id > 6 for update;

6-9有临键锁,5-9有间隙锁,换句话说,间隙锁与间隙锁不冲突,这里可以不谈读写锁的兼容性问题

image-20240921190741879

表1

image-20240921190738010

意向锁

​ 为避免加表锁时逐行查看行级锁的加锁情况这样的低效操作而加的隐式锁。需要注意的是:意向锁是表级锁,是对整个表加的

比如:

​ 当事务A执行一个update语句时,会加目标记录加X型行锁,也会给整个表加X型意向锁(IX)

​ 当事务B想给表加表 锁,会先查看表中有无意向锁,如果没有,则可以直接加表锁;如果有,则要考虑事务B要加的锁与当前意向锁是否兼容,兼容方可加。

加锁分析

如何看一个事务加了什么锁?

select * from performance_schema.data_locks;

其中:

  • lock_type字段说明锁的粒度,如全局锁、表级锁、行级锁;

  • lock_mode说明锁的类型。加锁默认一般是临键锁,有特殊情况会优化为其他锁,字段说明如下:

    1. SX这样无特殊说明的,就是临键锁
    2. REC_NOT_GAP这样,意为没有间隙记录,说明加的是记录锁
    3. GAP说明加的是间隙锁
    4. INSERT_INTENTION插入意向锁
  • index_name说明这个锁加在了哪个字段上

  • lock_data被锁住的区间右值,即上界

案例:

对于上面的表一:(id主键,sort二级唯一索引)

各语句加锁情况如下:

image-20240921205913475

image-20240921205919191

image-20240921205931036

image-20240921205938144

标签:事务,加锁,浅谈,间隙,记录,索引,意向锁,Mysql,机制
From: https://blog.csdn.net/weixin_74308571/article/details/142736940

相关文章

  • Django替换sqlite默认数据库到mysql的一系列操作
    将这部分注释掉:DATABASES={'default':{'ENGINE':'django.db.backends.sqlite3','NAME':BASE_DIR/'db.sqlite3',}} 并替换为:DATABASES={'default':{......
  • MySQL事务、索引、数据恢复和备份
    1事务1.1事务介绍事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。就比如:张三给李四转账1000块钱,张三银行账户的钱减少1000,而李四银行账户的钱要增加1000。这一组......
  • mysql占用内存过大问题排查
    如果MySQL占用内存过高,可以按照以下步骤进行排查:一、检查MySQL配置参数查看 innodb_buffer_pool_size:这个参数决定了InnoDB存储引擎缓冲池的大小,它会占用大量内存。如果设置得过大,可能导致内存占用过高。可以通过查询 SHOWVARIABLESLIKE'innodb_buffer_pool_size......
  • 基于SpringBoot+MySQL+SSM+Vue.js的电影票信息管理系统(附论文)
    获取见最下方名片获取见最下方名片获取见最下方名片演示视频基于SpringBoot+MySQL+SSM+Vue.js的电影票信息管理系统(附论文)技术描述开发工具:Idea/Eclipse数据库:MySQLJar包仓库:Maven前端框架:Vue/ElementUI后端框架:Spring+SpringMVC+Mybatis+SpringBoot......
  • 基于SpringBoot+MySQL+SSM+Vue.js的二手家电管理系统(附论文)
    获取见最下方名片获取见最下方名片获取见最下方名片演示视频基于SpringBoot+MySQL+SSM+Vue.js的二手家电管理系统(附论文)技术描述开发工具:Idea/Eclipse数据库:MySQLJar包仓库:Maven前端框架:Vue/ElementUI后端框架:Spring+SpringMVC+Mybatis+SpringBoot文......
  • 记宝塔面板MySQL启动失败问题之解决
    检查错误日志登录到宝塔面板。前往 软件管理 -> 数据库 ->选择对应的MySQL版本-> 查看日志。查看最近的错误信息,通常会给出启动失败的具体原因。检查MySQL配置文件配置文件通常位于 /etc/my.cnf 或 /etc/mysql/my.cnf。确保配置文件中的设置正确无误,例如数......
  • 深度解析Spring AI:请求与响应机制的核心逻辑
    我们在前面的两个章节中基本上对SpringBoot3版本的新变化进行了全面的回顾,以确保在接下来研究SpringAI时能够避免任何潜在的问题。今天,我们终于可以直接进入主题:SpringAI是如何发起请求并将信息返回给用户的。在接下来的内容中,我们将专注于这一过程,而流式回答和函数回调的相......
  • K8S配置MySQL主从自动水平扩展
    前提环境操作系统Ubuntu22.04K8S1.28.2集群(1个master+2个node)MySQL5.7.44部署在K8S的主从集群metrics-serverv0.6.4概念简介在K8s中扩缩容分为两种●Node层面:对K8s物理节点扩容和缩容,根据业务规模实现物理节点自动扩缩容●Pod层面:一般会使用Deployment中的Re......
  • 【K8s】专题十四(1):Kubernetes 安全机制之 RBAC
    本文内容均来自个人笔记并重新梳理,如有错误欢迎指正!如果对您有帮助,烦请点赞、关注、转发、订阅专栏!专栏订阅入口| 精选文章 | Kubernetes |Docker|Linux |羊毛资源 | 工具推荐 |往期精彩文章【Docker】(全网首发)KylinV10下MySQL容器内存占用异常的解决......
  • MySql基础:数据类型
    1.数据类型的整体分类    说明:在mysql表中建立属性列都是列名称在前类型在后。2.整数数据类型        说明:在MySQL中,整型可以指定是有符号的和无符号的,默认是有符号的。可以通过UNSIGNED来说明某个字段是无符号的类型字节最小值最大值(带符号的/无符......