博客
关于我
MySQL 的全局锁、表锁和行锁
阅读量:799 次
发布时间: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/

    你可能感兴趣的文章
    Node.js之async_hooks
    查看>>
    Node.js初体验
    查看>>
    Node.js升级工具n
    查看>>
    Node.js卸载超详细步骤(附图文讲解)
    查看>>
    Node.js卸载超详细步骤(附图文讲解)
    查看>>
    Node.js基于Express框架搭建一个简单的注册登录Web功能
    查看>>
    node.js学习之npm 入门 —8.《怎样创建,发布,升级你的npm,node模块》
    查看>>
    Node.js安装与配置指南:轻松启航您的JavaScript服务器之旅
    查看>>
    Node.js安装及环境配置之Windows篇
    查看>>
    Node.js安装和入门 - 2行代码让你能够启动一个Server
    查看>>
    node.js安装方法
    查看>>
    Node.js官网无法正常访问时安装NodeJS的方法
    查看>>
    node.js模块、包
    查看>>
    node.js的express框架用法(一)
    查看>>
    Node.js的交互式解释器(REPL)
    查看>>
    Node.js的循环与异步问题
    查看>>
    Node.js高级编程:用Javascript构建可伸缩应用(1)1.1 介绍和安装-安装Node
    查看>>
    nodejs + socket.io 同时使用http 和 https
    查看>>
    NodeJS @kubernetes/client-node连接到kubernetes集群的方法
    查看>>
    NodeJS API简介
    查看>>