MySQL-锁

文章目录

  • [一. MySQL中锁的作用](#一. MySQL中锁的作用)
  • [二. MySQL中有哪些锁](#二. MySQL中有哪些锁)
  • [三. 全局锁](#三. 全局锁)
    • [3.1 介绍全局锁](#3.1 介绍全局锁)
    • [3.2 全局锁语法](#3.2 全局锁语法)
    • [3.3 全局锁特点](#3.3 全局锁特点)
    • [3.4 不加锁备份](#3.4 不加锁备份)
  • [四. 表级锁](#四. 表级锁)
    • [4.1 表级锁介绍](#4.1 表级锁介绍)
    • [4.2 表锁](#4.2 表锁)
  • [4.3 元数据锁](#4.3 元数据锁)
    • [4.4 意向锁](#4.4 意向锁)
  • [五. 行锁](#五. 行锁)
    • [5.1 行锁的分类](#5.1 行锁的分类)
    • [5.2 行锁](#5.2 行锁)
    • [5.3 间隙锁&临键锁](#5.3 间隙锁&临键锁)

一. MySQL中锁的作用

用来保护并发访问数据库资源的线程安全问题,防止多个进程同时操作数据库,导致数据库的错误操作。

二. MySQL中有哪些锁

  1. 全局锁:锁定数据库中所有表。
  2. 表级锁:每次操作锁住整张表。
  3. 行级锁:每次操作锁住对应的行数据。

三. 全局锁

3.1 介绍全局锁

定义:全局锁就是对整个数据库实列加锁,加锁后整个实列变成只读状态,已经更新操作的事务提交语句都将被阻塞。

使用场景:做全库的逻辑备份,对于所有的表进行锁定,从而获取一致性视图,保证数据的完整性。

如上操作不加锁的话,就可能会导致备份的数据库有问题,比如上面有新的订单了,但是库存没有减少,因此我们备份时,需要加上全局锁。

3.2 全局锁语法

  1. 全局锁加锁
sql 复制代码
flush tables with read lock ;
  1. 数据备份
sql 复制代码
mysqldump -uroot --p123456 itcast > itcast.sql

这个不是SQL语句,mysqldump是一个备份的工具,该指令需要在终端命令行中执行。

  1. 全局锁释放
sql 复制代码
unlock tables ;

3.3 全局锁特点

  1. 如果在主库上备份,那么备份期间不能执行更新,业务基本上停摆。
  2. 如果在从库上备份,那么备份期间从库不能执行主库同步过来的二进制日志(binlog),会导致主从延迟。

3.4 不加锁备份

在innoDB引擎中,我们可以在备份时加上参数 --single-transaction 来完成不加锁的一致性数据备份。

sql 复制代码
mysqldeump --single-transaction -uroot -p123456 itcast> itcast.sql

四. 表级锁

4.1 表级锁介绍

表级锁,每次操作锁住整张表。锁定粒度大,发生锁冲突的概率最高,并发度最低。应用在MyISAM、InnoDB、BDB等存储引擎中。

表级锁有三类:

  1. 表锁
  2. 元数据锁
  3. 意向锁

4.2 表锁

表锁有两类:

  1. 表共享读锁:加锁后,该线程和其他线程可以读取表中数据,但都不能对表数据做写操作。

    语法:
sql 复制代码
lock tables 表名 read;
  1. 表独享写锁:加锁后,该线程可对表进行读和写,其他线程不能对该表进行操作,直到释放锁。

    语法:
sql 复制代码
lock tables 表名 write;

4.3 元数据锁

  1. 元数据锁,简称MDL。
    MDL加锁是系统自动进行的,不需要显式调用。但对表进行增删改查时,会加上MDL锁。在表上有活动事务的时候,不可以对元数据进行写入操作。为了避免DML与DDL冲突,保证读写的正确性。

这里的元数据可以理解为表的结构,也就是说当表涉及未提交事务时,是不能修改表的结构的。

在MySQL5.5中引入了MDL,对表进行增删改查SQL操作时,表会加上DML共享锁(共享);对表结构修改时,会加上DML排他锁(排他)。

  1. 常见的SQL操作时,所添加的元数据锁:
对应SQL 锁类型 说明
lock tables xxx read / write SHARED_READ_ONLY / SHARED_NO_READ_WRITE
select 、select ... lock in share mode SHARED_READ 与SHARED_READ、SHARED_WRITE兼容,与EXCLUSIVE互斥
insert 、update、delete、select ... for update SHARED_WRITE 与SHARED_READ、SHARED_WRITE兼容,与EXCLUSIVE互斥
alter table ... EXCLUSIVE 与其他的MDL都互斥
  1. 我们可以通过下面的SQL,来查看数据库中的元数据锁的情况:
sql 复制代码
select object_type,object_schema,object_name,lock_type,lock_duration from
performance_schema.metadata_locks ;

4.4 意向锁

  1. 介绍

    在DML操作时,会加上行锁,此时加表锁,会一行一行检查是否存在行锁。而意向锁就是,加行锁时,给表加上意向锁,从而根据意向锁的类型,判断能否加表锁。

  2. 意向锁分类

  • 意向共享锁(IS): 由语句select ... lock in share mode添加 。 与 表锁共享锁 (read)兼容,与表锁排他锁(write)互斥。
  • 意向排他锁(IX): 由insert、update、delete、select...for update添加 。与表锁共享锁(read)及排他锁(write)都互斥,意向锁之间不会互斥。

一旦事务提交了,意向共享锁、意向排他锁,都会自动释放。

可以通过以下SQL,查看意向锁及行锁的加锁情况:

sql 复制代码
select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from
performance_schema.data_locks;

五. 行锁

5.1 行锁的分类

行级锁,每次操作锁住对应的行数据。锁定粒度最小,发生锁冲突的概率最低,并发度最高。应用在InnoDB存储引擎中。

InnoDB的数据是基于索引组织的,行锁是通过对索引上的索引项加锁来实现的,而不是对记录加的

锁。对于行级锁,主要分为以下三类:

  • 行锁(Record Lock):锁定单个行记录的锁,防止其他事务对此行进行update和delete。在
    RC、RR隔离级别下都支持。
  • 间隙锁(Gap Lock):锁定索引记录间隙(不含该记录),确保索引记录间隙不变,防止其他事
    务在这个间隙进行insert,产生幻读。在RR隔离级别下都支持。
  • 临键锁(Next-Key Lock):行锁和间隙锁组合,同时锁住数据,并锁住数据前面的间隙Gap。
    在RR隔离级别下支持.

5.2 行锁

  1. InnoDB实现了以下两种类型的行锁:
  • 共享锁(S):允许一个事务去读一行,阻止其他事务获得相同数据集的排它锁。
  • 排他锁(X):允许获取排他锁的事务更新数据,阻止其他事务获得相同数据集的共享锁和排他锁。

同一行索引共享锁兼容共享锁,不兼容排他锁;而排他锁不兼容任何锁。

  1. 常见的SQL语句,在执行时,所加的行锁如下:
  2. 可以通过以下SQL,查看意向锁及行锁的加锁情况:
sql 复制代码
select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from
performance_schema.data_locks;
  1. 无索引行锁升级为表锁
    当我们对表中没有索引的字段进行操作时,上面表格中的锁会升级为表锁。
    当我们对该字段创建索引,就又可以正常加行锁了。

5.3 间隙锁&临键锁

防止数据幻读的情况。

  • 索引查询(唯一值),给不存在的值上锁时,锁为间隙锁。

    如图当我们查询19时,innoDB引擎会在29加上间隙锁。

  • 索引查询(非唯一值),向右遍历时最后一个值不满足查询需求时,next-key lock 退化为间隙锁。

    如图我们查询18时,因为18是非唯一的,所以我们需要给18加上临键锁和29加上间隙锁。

  • 索引上的范围查询(唯一索引)--会访问到不满足条件的第一个值为止。

查询的条件为id>=21,并添加共享锁。 此时我们可以根据数据库表中现有的数据,将数据分为三个部分:

(18,29]

(29,+∞]

所以数据库数据在加锁是,29的临键锁(包含29及29之前的间隙),正无穷的临键锁(正无穷及之前的间隙)。

相关推荐
金玉满堂@bj1 小时前
Django \+ MySQL 的标准 Web 项目搭建-初级练习小项目
前端·mysql·django
网络工程小王1 小时前
【LangGraph的工作流编排能力】学习笔记
java·服务器·数据库·人工智能·langchain
程序边界1 小时前
表空间目录自动创建:从一个小开关聊到云原生存储的那些事
数据库·oracle·dba
qingy_20461 小时前
Redis Zset 底层数据结构及其使用场景
数据结构·数据库·redis
哆啦A梦15881 小时前
11,Springboot3+vue3个人中心,修改密码
java·前端·javascript·数据库·vue3
ooseabiscuit1 小时前
Laravel 7.x 十大新特性解析
数据库
A-刘晨阳8 小时前
AI原生时序数据库选型指南:从数据存储到智能决策的范式跃迁
数据库·时序数据库·ai-native
HalvmånEver9 小时前
MySQL的增删改查命令合集合集
数据库·sql·oracle
不剪发的Tony老师10 小时前
dblab:一款基于终端的交互式数据库客户端
数据库·sql