《SQL与数据库基础》16. 锁
本文以 MySQL 为例
锁
锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的计算资源(CPU、RAM、I/O)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。
MySQL中的锁,按照锁的粒度分,分为以下三类:
- 全局锁:锁定数据库中的所有表。
- 表级锁:每次操作锁住整张表。
- 行级锁:每次操作锁住对应的行数据。
全局锁
全局锁就是对整个数据库实例加锁,加锁后整个实例就处于只读状态,后续的DML的语句,DDL语句,已经更新操作的事务提交语句都将被阻塞。
其典型的使用场景是做全库的逻辑备份,对所有的表进行锁定,从而获取一致性视图,保证数据的完整性。
加全局锁:
FLUSH TABLES WITH READ LOCK;
释放锁:
UNLOCK TABLES;
数据备份(Windows命令):
mysqldump [-h 数据库主机地址] -u用户 -p密码 要备份的数据库 > 保存路径及备份文件名.sql
数据备份的相关指令,在MySQL管理章节还会详细介绍
数据库中加全局锁,是一个比较重的操作,存在以下问题:
- 如果在主库上备份,那么在备份期间都不能执行更新,业务基本上就得停摆。
- 如果在从库上备份,那么在备份期间从库不能执行主库同步过来的二进制日志(binlog),会导致主从延迟。
在InnoDB引擎中,我们可以在备份时加上参数 --single-transaction 参数来完成不加锁的一致性数据备份。
mysqldump --single-transaction [-h 数据库主机地址] -u用户 -p密码 要备份的数据库 > 保存路径及备份文件名.sql
表级锁
表级锁,每次操作锁住整张表。锁定粒度大,发生锁冲突的概率最高,并发度最低。应用在MyISAM、InnoDB、BDB等存储引擎中。
对于表级锁,主要分为以下三类:
- 表锁
- 元数据锁(meta data lock,MDL)
- 意向锁
表锁
对于表锁,分为两类:
- 表共享读锁(read lock)
- 表独占写锁(write lock)
读锁不会阻塞其他客户端的读,但是会阻塞写,也会阻塞当前客户端的写。
写锁既会阻塞其他客户端的读,又会阻塞其他客户端的写。
锁类型:READ,WRITE
加锁:
LOCK TABLES 表名 锁类型;
释放锁:
UNLOCK TABLES;
客户端断开连接会自动释放锁。
元数据锁
meta data lock,元数据锁,简写MDL。
MDL加锁过程是系统自动控制,无需显式使用,在访问一张表的时候会自动加上。MDL锁主要作用是维护表元数据的数据一致性,在表上有活动事务的时候,不可以对元数据进行写入操作。为了避免DML与DDL冲突,保证读写的正确性。
这里的元数据,可以简单理解为一张表的表结构。也就是说,某一张表涉及到未提交的事务时,不能修改这张表的表结构。
在MySQL5.5中引入了MDL,当对一张表进行增删改查的时候,加MDL读锁(共享);对表结构进行变更操作的时候,加MDL写锁(排他)。
常见的SQL操作时,所添加的元数据锁:
| 对应SQL | 锁类型 | 说明 |
|---|---|---|
| lock tables 表名 锁类型 | 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都互斥 |
查看元数据锁加锁情况:
SELECT object_type, object_schema, object_name, lock_type, lock_duration FROM performance_schema.metadata_locks;
意向锁
为了避免DML在执行时,加的行锁与表锁的冲突,在InnoDB中引入了意向锁,使得表锁不用检查每行数据是否加锁,使用意向锁来减少表锁的检查。
意向锁分类:
- 意向共享锁(IS)
由语句 select ... lock in share mode 添加 。与表锁共享锁(read)兼容,与表锁排他锁(write)互斥。 - 意向排他锁(IX)
由insert、update、delete、select ... for update 添加。与表锁共享锁(read)及排他锁(write)都互斥,意向锁之间不会互斥。
一旦事务提交了,意向共享锁、意向排他锁都会自动释放。
查看意向锁及行锁加锁情况:
SELECT object_schema, object_name, index_name, lock_type, lock_mode, lock_data FROM performance_schema.data_locks;
行级锁
行级锁,每次操作锁住对应的行数据。锁定粒度最小,发生锁冲突的概率最低,并发度最高。应用在InnoDB存储引擎中。
InnoDB的数据是基于索引组织的,行锁是通过对索引上的索引项加锁来实现的,而不是对记录加的锁。
对于行级锁,主要分为以下三类:
- 行锁(Record Lock)
锁定单个行记录的锁,防止其他事务对此行进行 update 和 delete。在RC、RR隔离级别下都支持。 - 间隙锁(Gap Lock)
锁定索引记录间隙(不含该记录),确保索引记录间隙不变,防止其他事务在这个间隙进行 insert,产生幻读。在RR隔离级别下都支持。 - 临键锁(Next-Key Lock)
行锁和间隙锁组合,同时锁住数据,并锁住数据前面的所有间隙。在RR隔离级别下支持。
行锁
行锁,也叫记录锁。InnoDB实现了两种类型的行锁:
- 共享锁(S)
允许一个事务去读一行,阻止其他事务获得相同数据集的排它锁。 - 排他锁(X)
允许获取排他锁的事务更新数据,阻止其他事务获得相同数据集的共享锁和排他锁。
两种行锁的兼容情况如下:

常见的SQL语句,在执行时,所加的行锁如下:
| SQL | 行锁类型 | 说明 |
|---|---|---|
| INSERT ... | 排他锁 | 自动加锁 |
| UPDATE ... | 排他锁 | 自动加锁 |
| DELETE ... | 排他锁 | 自动加锁 |
| SELECT(正常) | 不加任何锁 | |
| SELECT ... LOCK IN SHARE MODE | 共享锁 | 需要手动在SELECT之后加LOCK IN SHARE MODE |
| SELECT ... FOR UPDATE | 排他锁 | 需要手动在SELECT之后加FOR UPDATE |
默认情况下,InnoDB在 REPEATABLE READ 事务隔离级别运行,InnoDB使用 next-key 锁进行搜索和索引扫描,以防止幻读。
- 针对唯一索引进行检索时,对已存在的记录进行等值匹配时,将会自动优化为行锁。
- InnoDB的行锁是针对于索引加的锁,不通过索引条件检索数据,那么InnoDB将对表中的所有记录加锁,此时就会升级为表锁。
查看意向锁及行锁的加锁情况:
SELECT object_schema,object_name,index_name,lock_type,lock_mode,lock_data FROM performance_schema.data_locks;
间隙锁
默认情况下,InnoDB在 REPEATABLE READ 事务隔离级别运行,InnoDB使用 next-key 锁进行搜索和索引扫描,以防止幻读。
- 索引上的等值查询(唯一索引),给不存在的记录加锁时,优化为间隙锁。
- 索引上的等值查询(非唯一普通索引),向右遍历时最后一个值不满足查询需求时,next-key lock 退化为间隙锁。
- 索引上的范围查询(唯一索引)会访问到不满足条件的第一个值为止。
间隙锁唯一目的是防止其他事务插入间隙。间隙锁可以共存,一个事务采用的间隙锁不会阻止另一个事务在同一间隙上采用间隙锁。
临键锁
临键锁,是记录锁与间隙锁的组合,它的封锁范围,既包含索引记录,又包含索引区间。
临键锁的主要目的,也是为了避免幻读(Phantom Read)。如果把事务的隔离级别降级为RC,临键锁则也会失效。
《SQL与数据库基础》16. 锁的更多相关文章
- C#面试题(转载) SQL Server 数据库基础笔记分享(下) SQL Server 数据库基础笔记分享(上) Asp.Net MVC4中的全局过滤器 C#语法——泛型的多种应用
C#面试题(转载) 原文地址:100道C#面试题(.net开发人员必备) https://blog.csdn.net/u013519551/article/details/51220841 1. . ...
- Sql Server数据库基础
--------------------------------------第一章 Sql Server数据库基础------------------------------------------ ...
- SQL Server 数据库基础笔记分享(下)
前言 本文是个人学习SQL Server 数据库时的以往笔记的整理,内容主要是对数据库的基本增删改查的SQL语句操作和约束,视图,存储过程,触发器的基本了解. 注:内容比较基础,适合入门者对SQL S ...
- sql Servers数据库基础
1. 数据库约束包含: ·非空约束 ·主键约束(PK) primary key constraint 唯一且不为空 ·唯一约束(UQ) unique constraint 唯一 ...
- SQL Server 数据库基础笔记分享(上)
前言 本文是个人学习SQL Server 数据库时的以往笔记的整理,内容主要是对数据库的基本增删改查的SQL语句操作和约束,视图,存储过程,触发器的基本了解. 注:内容比较基础,适合入门者对SQL S ...
- Sql Server 数据库事务与锁,同一事务更新又查询锁?期望大家来解惑
我有一个People表,有三行数据: 如果我们没详细了解数据库事务执行加锁的过程中,会不会有这样一个疑问:如下的这段 SQL 开启了事务,并且在事务中进行了更新和查询操作. BEGIN TRAN up ...
- DBA常用SQL之数据库基础信息
第一部分: 1. 查看oracle最大连接数 sql>show parameter processes #最大连接数 2. 修改最大连接数 sql>alter system set pro ...
- sql server 数据库基础知识(二)
CASE函数用法1:单值判断,相当于switch caseCASE expression WHEN value1 THEN returnvalue1 WHEN value2 THEN returnva ...
- 【2017-03-09】SQL Server 数据库基础、四种约束
一.数据库和内存的区别 数据库:一些存储在硬盘上的数据文件 内存:计算机临时存储的一些数据 二.常用数据库 .Net - SQL Server PHP - MySql Java - Oreacl 三. ...
- SQL Server数据库基础笔记
启动和停止SQL Server服务三种形式 后台启动服务 计算机->右键->管理->服务和应用程序->服务->sql server(MSSQLSERVER) SQL Se ...
随机推荐
- 从前后端的角度分析options预检请求
摘要:options预检请求是干嘛的?options请求一定会在post请求之前发送吗?前端或者后端开发需要手动干预这个预检请求吗?不用文档定义堆砌名词,从前后端角度单独分析,大白话带你了解! 本文分 ...
- 自定义组件模拟v-model
在项目中常常会遇到一个组件中引入好几个子组件的情况,而引入的子组件和子组件之间又需要有数据交互,如果使用父组件作为桥梁进行数据交互这个也是可以的,只是有些麻烦,so最理想的是子组件和子组件自己去交互, ...
- 分布式机器学习(Parameter Server)
分布式机器学习中,参数服务器(Parameter Server)用于管理和共享模型参数,其基本思想是将模型参数存储在一个或多个中央服务器上,并通过网络将这些参数共享给参与训练的各个计算节点.每个计算节 ...
- 【QCustomPlot】性能提升之修改源码(版本 V2.x.x)
说明 使用 QCustomPlot 绘图库的过程中,有时候觉得原生的功能不太够用,比如它没有曲线平滑功能:有时候又觉得更新绘图数据时逐个赋值效率太低,如果能直接操作内存就好了:还有时候希望减轻 CPU ...
- 在C++中,传值还是传引用?
情况一:需要修改原对象 需要修改原对象的情况,必须要传引用.这种情况没什么要说的. 情况二:不需要修改原对象 对于内置类型(整数.浮点数.字符类型等),传值效率更高.主要有三点原因: 内存开销更小.由 ...
- /etc/netplan/network-manager-all.yaml 配置服务器ip
本文为博主原创,转载请注明出处: /etc/netplan 是用于配置 Ubuntu 系统网络接口的目录.在 Ubuntu 中,网络配置的默认工具为 Netplan,而 /etc/netplan 则 ...
- 00.Webstrom的基本入门设置
1.取消红框类自动打开项目 2.打开轮滚缩放代码 3.设置代码字体,这里选择的是Consolas 推荐免费字体:https://files.cnblogs.com/files/huadaxia/jet ...
- Python自学指南-第一章-安装运行
1.1 [环境]快速安装 Python 与PyCharm "工欲善其事,必先利其器",为了自学之路的顺利顺利进行.首先需要搭建项目的开发环境. 1. 下载解释器 进入 Python ...
- C++面试八股文:知道std::unordered_set/std::unordered_map吗?
某日二师兄参加XXX科技公司的C++工程师开发岗位第27面: 面试官:知道std::unordered_set/std::unordered_map吗? 二师兄:知道.两者都是C++11引入的新容器, ...
- ElasticSearch - 批量更新bulk死锁问题排查
一.问题系统介绍 监听商品变更MQ消息,查询商品最新的信息,调用BulkProcessor批量更新ES集群中的商品字段信息; 由于商品数据非常多,所以将商品数据存储到ES集群上,整个ES集群共划分了2 ...