博客
关于我
MySQL 的全局锁、表锁和行锁
阅读量:814 次
发布时间:2023-02-11

本文共 2255 字,大约阅读时间需要 7 分钟。

在前一篇文章中,我已经简单介绍了MySQL的全局锁、表级锁和行级锁,其中行级锁仅仅提到了概念,但没有深入讲解。由于行级锁的加锁规则较为复杂,不同场景下加锁的形式也不同,因此本文将深入探讨行级锁的具体实现机制。

在数据库管理系统中,行级锁是最常用的锁定机制之一,其最基本的加锁单位是next-key lock。这个锁定机制由记录锁和间隙锁组合而成。具体来说,next-key lock表示的是前开后闭的区间,而间隙锁则表示前开后开的区间。

需要注意的是,在某些特定场景下,next-key lock会退化为记录锁或间隙锁。那么,这些具体的退化场景又是什么样的呢?为了更好地理解这一点,我们可以通过以下表结构和实际操作来进行实验说明。

以下是我们实验使用的表结构:

id b a
8 8 8
9 9 9
16 16 16

需要注意的是,我使用的是MySQL 8.0.26版本,由于不同版本的MySQL可能会有不同的加锁规则,这也是理解行级锁加锁机制的重要基础。

接下来,我们将从以下几个方面来分析行级锁的加锁规则:

  • 唯一索引等值查询

    • 当查询的记录存在时,next-key lock会退化为记录锁。
    • 当查询的记录不存在时,next-key lock会退化为间隙锁。
  • 非唯一索引等值查询

    • 当查询的记录存在时,除了next-key lock,还会额外加间隙锁。
    • 当查询的记录不存在时,只会加next-key lock,然后会退化为间隙锁。
  • 非唯一索引范围查询

    • 行级锁的加锁规则在非唯一索引范围查询中与唯一索引有所不同。普通索引范围查询中,next-key lock不会退化为间隙锁和记录锁。
  • 为了更直观地理解这些加锁规则,我们可以通过以下具体案例来分析。

    案例一:唯一索引等值查询

    假设我们执行以下两个更新操作:

    update t_test set a = 1 where id = 8 for update;update t_test set a = 1 where id > 8 and id < 9 for update;

    在执行这两个查询时,分别分析加锁情况:

    • 对于第一个查询update t_test set a = 1 where id = 8 for update,由于id是唯一索引且记录存在,next-key lock会退化为记录锁,锁定范围仅限于id=8这一行。

    • 对于第二个查询update t_test set a = 1 where id > 8 and id < 9 for update,由于id是唯一索引且记录不存在,next-key lock会退化为间隙锁,锁定范围为(8,16)。

    因此,会话2在尝试往间隙锁中插入id=9的记录时会被锁定,而会话3修改id=16的记录也会被锁定。

    案例二:非唯一索引等值查询

    假设我们执行以下两个更新操作:

    update t_test set a = 1 where b = 8 for update;update t_test set a = 1 where b > 8 and b < 16 for update;

    分析加锁情况:

    • 对于第一个查询update t_test set a = 1 where b = 8 for update,由于b是非唯一索引且记录存在,next-key lock会加在b=8这一行,同时还会额外加间隙锁,锁定范围为(8,16)。

    • 对于第二个查询update t_test set a = 1 where b > 8 and b < 16 for update,由于b是非唯一索引且记录不存在,next-key lock会加在b=8到b=16的范围内,但由于是普通索引,next-key lock不会退化为间隙锁,因此锁定范围为(8,16]。

    因此,会话2在尝试往间隙锁中插入b=9的记录时会被锁定,而会话3修改b=16的记录也会被锁定。

    案例三:非唯一索引范围查询

    假设我们执行以下两个更新操作:

    update t_test set a = 1 where b = 8 for update;update t_test set a = 1 where b > 8 and b < 16 for update;

    分析加锁情况:

    • 对于第一个查询update t_test set a = 1 where b = 8 for update,由于b是非唯一索引且记录存在,next-key lock会加在b=8这一行,同时还会额外加间隙锁,锁定范围为(8,16)。

    • 对于第二个查询update t_test set a = 1 where b > 8 and b < 16 for update,由于b是非唯一索引且记录不存在,next-key lock会加在b=8到b=16的范围内,但由于是普通索引,next-key lock不会退化为间隙锁,因此锁定范围为(8,16]。

    因此,会话2在尝试往间隙锁中插入b=9的记录时会被锁定,而会话3修改b=16的记录也会被锁定。

    通过以上案例可以看出,行级锁的加锁规则在不同的查询场景下表现出不同的特点。理解这些规则对于数据库的并发控制和高并发场景的优化具有重要意义。

    总的来说,行级锁的加锁机制相当复杂,理解这些细节对于优化数据库性能和解决并发控制问题至关重要。通过实际案例的实验,我们可以更直观地看到不同类型的索引在行级锁中的表现差异,并为实际应用中的锁定策略提供参考依据。

    转载地址:http://gfbfk.baihongyu.com/

    你可能感兴趣的文章
    Python制作进度条,原来有这么多方法
    查看>>
    Python制作简单的学生成绩管理系统
    查看>>
    python制作甘特图的基本知识(附Demo)
    查看>>
    python制作一个简单的服务器,【Python】 做一个简单的 http 服务器
    查看>>
    Python到底能做什么?它的优点在哪?
    查看>>
    python利用pytorch库导出图像分割算子
    查看>>
    python利用pyshark监听网卡来抓包其中pyshark中摸索的一些可用参数
    查看>>
    python利用excel分析过杀漏失
    查看>>
    python判断汉字数目
    查看>>
    python判断文件是空的,如果是空的,就删除
    查看>>
    python判断密码是否正确_python密码判断是否符合要求的方法
    查看>>
    python判断字符串包含中文_Python 判断字符串是否包含中文
    查看>>
    python删除第一行_Python 乱码指北:一行删掉根目录
    查看>>
    Python删除列表元素的三种方法
    查看>>
    python初步学习-python数据类型-集合(set)
    查看>>
    python列表生成字典_Python中将字典转换为列表的方法
    查看>>
    python列表对应元素合并为列表及判断一个列表是几维
    查看>>
    python列表去重复后按照顺序_从包含不可共元素的Python列表中删除重复元素,同时保留顺序?...
    查看>>
    python列表前几个_python之列表
    查看>>
    python列表元组
    查看>>