MySQL锁,你真的理解么?

本文涉及的产品
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDS DuckDB + QuickBI 企业套餐,8核32GB + QuickBI 专业版
RDS AI 助手,专业版
简介: 云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! 1、基本概念 锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中的数据也是一种供多个用户使用的共享资源,当多个用户并发地存取数据时,在数据库加锁的目的可以保证数据库数据的一致性。

云栖号资讯:【点击查看更多行业资讯
在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来!


1、基本概念

锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中的数据也是一种供多个用户使用的共享资源,当多个用户并发地存取数据时,在数据库加锁的目的可以保证数据库数据的一致性。

锁的类型

在数据库中,对数据的操作其实只有两种,即读和写,所以可用共享锁和互斥锁实现,即共享锁间之间是兼容的,而互斥锁间不兼容。

  • 共享锁(读锁):允许事务读
  • 互斥锁(写锁):允许事务删除或者更新一行数据

共享锁代表了读操作、互斥锁代表了写操作,所以我们可以在数据库中并行读,但是只能串行写,只有这样才能保证不会发生线程竞争,实现线程安全。

锁的粒度

我们按照锁的粒度可以分为全局锁、表锁和行锁,不同的存储引擎拥有的锁粒度是不同的

1

在下面的文章中,我们按照锁粒度的划分分别学习全局锁、表级锁和行锁

2、全局锁

2.1基本概念

从名称上就可以看出,全局锁是对整个数据库实例加锁。MySQL提供了一个加全局读锁的方法,即Flush tables with read lock (FTWRL)。当对数据库使用这个命令时,数据库将会处于只读状态,之后的其它线程的语句:如数据更新语句(数据的增删改)DML,数据的定义语句(表结构的修改)DDL均会被阻塞。

2.2使用场景

全局锁的典型使用场景是做数据库逻辑备份,也就是将整个库中的所有表都select出来存成文本。在备份过程中的整个库要处于只读状态,这会存在以下问题

  • 如果你在主库上备份,那么在备份期间都不能执行更新,业务基本上就能停止
  • 如果你在从库上备份,那么备份期间从库不能执行主库同步过来的binlog,会导致主从延迟。

如果选用的引擎不支持事务(如MyISAM),在对数据库做逻辑备份时只能选择FTWRL。如果引擎支持事务,并且支持可重复读的隔离级别(如InnoDB),我们就可以用一致性视图来做备份,MySQL自带的逻辑备份工具是mysqldump。当mysqldump使用参数-single-transaction时,导入数据之前就可以启动一个事务,来确保拿到一致性视图。在MVCC的支持下,导入数据的过程中是可以正常更新的。

2.3lock/unlock命令

全局锁加锁命令

flush tables with read lock

释放全局锁的命令

unlock tables

断开连接也能释放全局锁

3、表级锁

MySQL的表级锁有两种:表锁,元数据锁(meta data lock MDL),

3.1表锁

表锁的语法是:lock tables ... read/write,可以利用unlock tables主动释放锁,也可以在连接断开时自动释放。需要注意的是,lock tables除了限制其它线程的读写,也会限制自身接下来的操作对象

举例

如果在某个线程 A 中执行 lock tables t1 read, t2 write这个语句,则其他线程写 t1、读写 t2 的语句都会被阻塞。与此同时,线程 A 在执行 unlock tables 之前,也只能执行读 t1、读写 t2 的操作。连写 t1 都不允许,自然也不能访问其他表。

这种操作整个表的影响很大,所以对于使用InnoDB引擎下,一般不适用lock tables命令控制并发。

3.2MDL

MDL全称是metadata lock,即元数据锁,它的作用主要是为了维护表中数据的一致性,即用于解决DDL操作与DML操作的一致性。

解决的问题

其主要解决了2个问题,一个是事务隔离问题,比如在可重复隔离级别下,会话A在2次查询期间,会话B对表结构做了修改,两次查询结果就会不一致,无法满足可重复读的要求;另外一个是数据复制的问题,比如会话A执行了多条更新语句期间,另外一个会话B做了表结构变更并且先提交,就会导致slave在重做时,先重做alter,再重做update时就会出现复制错误的现象。

元数据锁是server层的锁,表级锁,每执行一条DML、DDL语句时都会申请MDL锁,DML操作需要MDL读锁,DDL操作需要MDL写锁(MDL加锁过程是系统自动控制,无法直接干预,读读共享,读写互斥,写写互斥),申请MDL锁的操作会形成一个队列,队列中写锁获取优先级高于读锁。

NOTE:一旦出现写锁等待,不但当前操作会被阻塞,同时还会阻塞后续该表的所有操作(读操作当然也会被阻塞)。事务一旦申请到MDL锁后,直到事务执行完才会将锁释放。

MDL锁一旦发生可能会对数据库的业务带来其它的影响,因为后续对该表的访问都会被阻塞,造成连接积压。那么我们该如何避免MDL锁的发生呢?

MDL锁的优化

  • 避免长事务
  • 在DDL操作中设定等待时间

4、行锁

行锁每次锁定的是一行数据,行级锁定不是MySQL自己实现锁定的方式,是由存储引擎实现的(InnoDB)自己实现的。
InnoDB实现了以下两种类型的行锁

  • 共享锁(读锁)

允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。若事务T对数据对象A加上共享锁,则事务T可以读A但不能修改A,而其他事务只能再对对象A加共享锁,而不能加排他锁,直到事务T释放A上的共享锁。这保证了其他事务可以读A,但在事务T释放A上的S锁之前不能对A做任何修改。

  • 排他锁(写锁)

允许获取排他锁的事务更新数据,阻止其他事务取得相同的数据集共享读锁和排他写锁。若事务T对数据对象A加上排他锁,事务T可以读A也可以修改A,其他事务不能再对A加任何锁,直到T释放A上的锁

NOTE:排他锁指的是一个事务在一行数据加上排他锁后,其他事务不能再在其上加其他的锁。mysql InnoDB引擎默认的修改数据语句:update,delete,insert都会自动给涉及到的数据加上排他锁,select语句默认不会加任何锁类型,如果加排他锁可以使用select …for update语句,加共享锁可以使用select … lock in share mode语句。所以加过排他锁的数据行在其他事务种是不能修改数据的,也不能通过for update和lock in share mode锁的方式查询数据,但可以直接通过select …from…查询数据,因为普通查询没有任何锁机制。

为了使得表锁和行锁共存,实现多粒度锁机制,InnoDB存在了两种内部使用的的意向锁

  • 意向共享锁

事务打算给数据行共享锁,事务在给一个数据行加共享锁前必须先取得该表的意向共享锁。

  • 意向排他锁

事务打算给数据行加排他锁,事务在给一个数据行加排他锁前必须先取得该表的意向排他锁

NOTE:意向锁是InnoDB自动加的,不需用户干预。对于UPDATE、DELETE和INSERT语句,InnoDB会自动给涉及数据集加排他锁;对于普通SELECT语句,InnoDB不会加任何锁。

  • 死锁

当并发系统中不同线程出现循环资源依赖,涉及的线程都在等待别的线程释放资源时,就会导致这几个线程都进入无限等待的状态,称为死锁。

案例

2

事务 A 在等待事务 B 释放 id=2 的行锁,而事务 B 在等待事务 A 释放 id=1 的行锁。 事务 A 和事务 B 在互相等待对方的资源释放,就是进入了死锁状态。

解除死锁的策略

  • 设置超时时间参数innodb_lock_wait_timeout
  • 将参数 innodb_deadlock_detect 设置为 on,发起死锁检测,当发现死锁后,主动回滚死锁链条中的某一个事务,让其它事务得以继续执行。

间隙锁(Next-key)

当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的 索引项加锁。对于键值在条件范围内但并不存在的记录叫做“间隙(GAP)”,InnoDB也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁 (Next-Key锁)。

使用间隙锁的目的是防止幻读。

【云栖号在线课堂】每天都有产品技术专家分享!
课程地址:https://yqh.aliyun.com/live

立即加入社群,与专家面对面,及时了解课程最新动态!
【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK

原文发布时间:2020-06-21
本文作者:Simon郎公众号
本文来自:“掘金”,了解相关信息可以关注“掘金”

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
SQL AliSQL 关系型数据库
MYSQL的全局锁和表锁
本文介绍了MySQL中的锁机制,包括全局锁、表级锁及其应用场景。全局锁通过`Flush tables with read lock (FTWRL)`实现,主要用于全库逻辑备份,但会阻塞更新和结构变更操作。表级锁分为显式表锁(`lock tables`)和元数据锁(MDL),前者用于控制并发访问,后者自动加锁以确保读写正确性。文章还探讨了如何安全地为小表添加字段,建议通过设置DDL等待时间或使用MariaDB/AliSQL的NOWAIT/WAIT功能避免业务阻塞。这些方法有助于在高并发场景下优化数据库性能与安全性。
347 0
|
SQL 关系型数据库 MySQL
MySQL 锁
MySQL里常见的几种锁
356 3
|
关系型数据库 MySQL 网络安全
如何排查和解决PHP连接数据库MYSQL失败写锁的问题
通过本文的介绍,您可以系统地了解如何排查和解决PHP连接MySQL数据库失败及写锁问题。通过检查配置、确保服务启动、调整防火墙设置和用户权限,以及识别和解决长时间运行的事务和死锁问题,可以有效地保障应用的稳定运行。
527 25
|
存储 关系型数据库 MySQL
MySQL进阶突击系列(06)MySQL有几种锁?| 别背答案,现场演示一下
本文详细解析了MySQL InnoDB存储引擎的锁机制,涵盖读锁、写锁、意向锁、记录锁、间隙锁和临键锁等8种锁类型。重点探讨了不同锁类型的加锁与释放方式,以及事务并发场景下的实战验证。通过具体示例,展示了在不同情况下锁的行为及其对事务的影响。文章还特别强调了锁的作用范围主要是索引,并解释了锁如何影响数据的读写操作。最后总结了并发事务中加锁规则,帮助读者深入理解MySQL的锁机制。
|
存储 关系型数据库 MySQL
优化 MySQL 的锁机制以提高并发性能
【10月更文挑战第16天】优化 MySQL 锁机制需要综合考虑多个因素,根据具体的应用场景和需求进行针对性的调整。通过不断地优化和改进,可以提高数据库的并发性能,提升系统的整体效率。
841 1
|
关系型数据库 MySQL Java
MySQL数据锁:Record Lock,Gap Lock 和 Next-Key Lock
本文基于 MySQL 8.0.30 版本及 InnoDB 引擎,深入解析三种行锁机制:记录锁(Record Lock)、间隙锁(Gap Lock)和临键锁(Next-key Lock)。记录锁锁定索引记录,确保事务唯一修改;间隙锁锁定索引间的间隙,防止新记录插入;临键锁结合两者,锁定范围并记录自身,有效避免幻读现象。通过具体示例展示了不同锁的作用机制及其在并发控制中的应用。
1575 2
|
监控 关系型数据库 MySQL
MySQL锁机制与解决死锁问题
MySQL锁机制与解决死锁问题
724 5
|
存储 关系型数据库 MySQL
MySQL数据库锁:共享锁和独占锁
本文详细介绍了`InnoDB`存储引擎中的两种行级别锁:共享锁(S锁)与排他锁(X锁)。通过具体示例展示了这两种锁的工作机制及其在`InnoDB`与`MyISAM`引擎中的表现差异。文章还提供了锁的兼容性矩阵,帮助读者更好地理解锁之间的互斥关系。最后总结了两种锁的特点及适用场景。适合希望深入了解`MySQL`并发控制机制的读者阅读。
713 1
|
关系型数据库 MySQL 数据库
Mysql的锁
本文介绍了MySQL中表级锁和行级锁的区别,其中MyISAM仅支持表级锁,而InnoDB支持表级锁和行级锁,默认为行级锁。表级锁锁定整个表,实现简单,资源消耗少,但并发度低;行级锁仅锁定相关记录,减少冲突,提高并发度,但加锁开销大。此外,还介绍了共享锁和排他锁的概念及意向锁的作用。
220 1
|
SQL 存储 关系型数据库
"MySQL增列必锁表?揭秘InnoDB在线DDL,让你的数据库操作飞一般,性能无忧!"
【8月更文挑战第11天】在数据库领域,MySQL凭借其稳定高效的表现深受开发者喜爱。对于是否会在给数据表添加列时锁表的问题,MySQL的行为受版本、存储引擎等因素影响。从5.6版起,InnoDB支持在线DDL,可在改动表结构时保持表的可访问性,避免长时间锁表。而MyISAM等则需锁表完成操作。例如,在使用InnoDB的表上运行`ALTER TABLE users ADD COLUMN email VARCHAR(255);`时,通常不会完全锁表。虽然在线DDL提高了灵活性,但复杂操作或大表变更仍可能暂时影响性能。因此,进行结构变更前应评估其影响并择机执行。
382 6

推荐镜像

更多