MySQL学习(19):锁

news/2024/9/25 10:47:36/

1.什么是锁

锁是计算机协调多个进程或线程并发访问某一资源的机制。

在数据库中,数据是供许多用户共享的资源,数据库必须保证数据并发访问的一致性、有效性,这就要靠锁来协调实现。

MySOL中的锁,分为以下三类:

(1)全局锁:锁定数据库中的所有表

(2)表级锁:每次操作锁住整张表

(3)行级锁:每次操作锁住对应的行数据

2.全局锁

2.1全局锁的作用

全局锁就是对整个数据库实例加锁,加锁后整个实例就处于只读状态(DML、DDL不可执行,DQL可执行)已经更新操作的事务提交语句都将被阻塞。

其典型的使用场景是做全库的逻辑备份,对所有的表进行锁定,保证数据的完整性、一致性。

数据库的备份是逐表进行的,可能刚刚完成了A表的备份,与A表相关的B表又更新了数据,造成了数据的不一致,因此备份前要加上全局锁

2.2实例备份

2.2.1使用全局锁的方法

(1)先进入数据库,通过以下命令创建全局锁:

flush tables with read lock;

(2)创建全局锁后,退出数据库,在windows或linux的命令行界面使用以下命令进行备份:

mysqldump -u登录数据库的用户 -p密码 数据库名>文件名
#-u与-p和后面的内容之间是没有空格的
#命令中的文件名,指的就是数据被复制后,存储到了这个文件里
#如果操作的不是本地数据库,而是远程连接的,那么就需要在命令里加上 -h 远程数据库ip

(3)备份完成后,再进入数据库,输入以下命令解开全局锁:

unlock tables;

2.2.2不使用全局锁的方法

由于数据库中加全局锁是一个比较重的操作,且存在以下问题:

(1)如果在主库上备份,那么在备份期间都不能执行更新,业务基本上就得停摆。

(2)如果在从库上备份,那么在备份期间从库不能执行主库同步过来的二进制日志(binlog),会导致主从延迟

因此实际生产中要慎用全局锁。

在InnoDB引擎环境下,还有一种不使用全局锁实现一致性备份数据库的方法,只需在mysqldump命令里添加一个参数即可:

mysqldump --single-transaction -u登录数据库的用户 -p密码 数据库名>文件名
#注意--single-transaction没有空格

3.表级锁

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

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

(1)表锁

(2)元数据锁(meta data lock,MDL)

(3)意向锁

3.1表锁

表锁分为两类:

(1)表共享读锁,简称读锁

(2)表独占写锁,简称写锁

执行锁操作的会话其他会话
读锁只可读(只能DQL,不能DML、DDL)只可读(只能DQL,不能DML、DDL)
写锁可读可写(DQL、DML、DDL都可以)不可读不可写(DQL、DML、DDL都不可以)

语法:

lock tables 表名 read或write;
#加锁
unlock tables;
#解锁,这条命令会解锁当前会话下的所有表锁

表锁是以会话为分界的,而不是以客户端为分界的,也不是以mysql用户为分界的。也就是说,在当前会话加了写锁,其他会话就无法读写(哪怕是同一客户端同一mysql用户)

3.2元数据锁

*元数据锁(MDL)是系统自动添加的,无需手动使用

*元数据锁是用来防止DML与DDL起冲突的

要明白元数据锁的作用,需要先回顾一下事务的4个隔离级别,其中mysql默认隔离级别Repeatable Read正是靠元数据锁来实现的

元数据锁也有共享读锁与独占写锁,二者相互排斥:

(1)当在一个事务中对某个表进行增删改查(DQL、DML)时,系统会自动给这个表加上共享读锁。其他事务可以对这个表进行增删改查,但不能修改表结构(DDL)

(2)当在一个事务中对某个表进行了修改表结构,即DDL操作(alter table ...),那么系统就会自动给这个表加上独占写锁,其他事务既不可对该表进行增删改查(DQL、DML),也不可修改表结构(DDL)

事务提交后,元数据锁会自动解开

3.3意向锁

对表进行DML操作时,系统会暂时给被操作的数据行加上行锁,如果这时还要给该表加上表锁,就会造成行锁与表锁的冲突(即DML自动添加的行锁与表锁的冲突),为了解决这个冲突的问题,就需要使用意向锁。

简单来说,意向锁是在进行DML操作时与行锁一起添加的,有了意向锁后,再要添加表锁,系统就会先判断表锁与所添加的意向锁是否兼容,如果兼容则可以加表锁,否则就不可。

意向锁有2种:

(1)意向共享锁(IS)

可由以下语句添加:

select... lock in share mode

IS与读锁(read)兼容,与写锁(write)互斥,也就是说,添加了IS后,可以对表加读锁,但不能加写锁

(2)意向排他锁(IX)

insert语句、update语句、delete语句会自动添加意向排他锁,select语句可由以下语句添加:

select...for update

IX与读锁、写锁都互斥

3.4三种表级锁总结

是否是系统自动添加对表的作用一句话总结有啥用
元数据锁我对这张表进行增删改时,你也可以进行增删改,但你不能更改表结构(DDL)解决DDL与DML的冲突
表锁读锁(read)

我不能对表增删改(DML),只能查(DQL)

你也一样。

就锁表用的,你用你就加,不用就不加

写锁

(write)

我可以对表增删改

你都不可以

意向锁意向共享锁(IS)表可以加read,不能加write解决DML自动添加的行锁与表锁的冲突
意向排他锁(IX)执行增删改时是自动,执行时需手动添加表read、write都不能加

4.行级锁

*行级锁:每次操作锁住对应的行数据。锁定粒度最小,发生锁冲突的概率最低,并发度最高。

*应用在InnoDB存储引擎中。

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

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

(1)行锁(Record Lock):锁定单个行记录的锁,防止其他事务对此行进行update和delete。在RC、RR事务隔离级别下都支持

(2)间隙锁(Gap Lock):锁定索引记录间隙(不含该记录),确保索引记录间隙不变,防止其他事务在这个间隙进行insert,产生幻读。在RR事务隔离级别下支持。

(3)临键锁(Next-key Lock):行锁+间隙锁。在RR事务隔离级别下支持。

4.1行锁

4.1.1共享锁与排他锁

InnoDB实现了以下2种行锁

(1)共享锁(S):其他事务可以和当前事务一起读一行带有S的数据。共享锁之间可兼容,但与排他锁互斥。

(2)排他锁(X):若某行数据被加上了排他锁,那么就只有当前事务能操作它,其他事务不能删改,也不能查。排他锁之间也是互斥的

4.1.2加锁以及查看锁

可以看到行锁的加锁情况与意向共享锁相同,也就说明二者会同时添加

不要忘了意向共享锁是为了解决行锁与表锁的冲突才设置的,因此二者才会同时添加 

*通过下图语句可以查看系统内的锁,其中IS是意向共享锁,

S,REC_NOT_GAP是共享锁,S,GAP是间隙锁,S是临键锁

4.1.3行锁自动升级为表锁的情况

InnoDB行锁是针对索引的锁,如果对没有索引的字段加行锁,那么行锁就会自动升级为表锁

比如在事务A中修改a字段的数据(update),同时a字段没有索引,那么由于update操作自动给这行数据添加了排他锁,同时由于a字段没有索引,这个排他锁自动升级为表锁,这个表的每一行数据就都要收到排他锁的限制,事务B不能对这个表进行增删改查

4.2间隙锁与临键锁

RR隔离级别下不同索引在不同查询情况下的加锁类型:

非唯一索引范围查询临键锁
等值查询查询的值存在临键锁+间隙锁
查询的值不存在间隙锁
唯一索引范围查询行锁+间隙锁
等值查询查询的值存在行锁
查询的值不存在间隙锁

具体加锁过程可见如下连接:

间隙锁详解icon-default.png?t=N7T8https://blog.csdn.net/w15558056319/article/details/122861509?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522172309730016800182785516%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=172309730016800182785516&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-23-122861509-null-null.142^v100^pc_search_result_base5&utm_term=%E9%97%B4%E9%9A%99%E9%94%81&spm=1018.2226.3001.4187


http://www.ppmy.cn/news/1506319.html

相关文章

Open3D 三维重建-Poisson Surface Reconstruction (泊松曲面重建)

目录 一、概述 1.1原理 1.2实现步骤 1.3应用 二、代码实现 2.1关键函数 2.1.1函数代码 2.1.2参数详解 2.1.3名词解释 2.2完整代码 三、实现效果 3.1原始点云 3.2重建后点云 3.3去除低密度点云 Open3D点云算法汇总及实战案例汇总的目录地址: Open3D点…

AcWing 714. 连续奇数的和 1

给定两个整数 XX 和 YY,输出在他们之间(不包括 XX 和 YY)的所有奇数的和。 输入格式 第一行输入 XX,第二行输入 YY。 输出格式 输出一个整数,表示所有满足条件的奇数的和。 数据范围 −100≤X,Y≤100−100≤X,Y≤…

【Canvas与艺术】蓝波纹白底黄星徽章

【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>蓝波纹白底黄星徽章</title><style type"text/css&quo…

算法的效率度量——时间复杂度

算法的效率度量 算法的效率度量: 时间复杂度空间复杂度 时间复杂度 如何评估算法的时间开销? ——让算法先运行&#xff0c;事后统计运行时间&#xff1f; 存在问题: 和机器性能有关。如&#xff1a;超级计算机VS单片机和编程语言有关&#xff0c;越高级的语言执行效率越低…

vs+qt一些问题

一直遇到的两个问题&#xff0c;今天解决了 1、 因为前后端分离&#xff0c;前端写完了&#xff0c;后端还在一直修改&#xff0c;但是每次都是单独打开的后端的sln&#xff0c;所以会出现这个&#xff0c;把前端的模块删掉就好了。 2、打开vs项目&#xff0c;很多报错&#…

高级网络渗透测试技术(第一篇)

一、概述 网络渗透测试&#xff08;Penetration Testing, Pen Test&#xff09;是通过模拟恶意攻击者的行为来评估计算机系统、网络或Web应用的安全性。高级网络渗透测试技术则涵盖了更复杂和深入的测试方法&#xff0c;能够更有效地发现并利用系统中的潜在漏洞。 二、前期准…

Bytebase 2.22.1 - SQL 编辑器展示更丰富的 Schema 信息

&#x1f680; 新功能 SQL 编辑器直接展示表&#xff0c;视图&#xff0c;函数&#xff0c;存储过程等各种 Schema 详情。OpenAI 功能进入社区版&#xff08;免费&#xff09;&#xff0c;现在您可以通过配置自有 OpenAI key 在 SQL 编辑器中启用自然语言转 SQL 功能。支持在 …

JavaScript - 变量声明(let、const 和其他)

目录 一、引言 1. let 的作用 2. const 的作用 3. let 与 const 的选择 4. let 和 const 的性能 5. var, let, const 的对比 6. 常见误区 二、其他变量定义 1. var 关键字 2. 全局对象属性 3. 使用 IIFE&#xff08;立即调用函数表达式&#xff09; 4. ES6 模块 总结 …