阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

MySQL锁机制深入理解

408次阅读
没有评论

共计 3893 个字符,预计需要花费 10 分钟才能阅读完成。

本文参考自 MySQL 官网 5.6 版本参考手册的 14.5.1, 此小节说明 MySQL 的锁分类,此外还有 14.5.2 小节和 14.5.3 小节详述事务隔离级别和各 SQL 语句的加锁模式,后两节将单独写 2 篇笔记。

  • https://dev.mysql.com/doc/refman/5.6/en/innodb-locking.html
  • https://dev.mysql.com/doc/refman/5.6/en/innodb-transaction-isolation-levels.html
  • https://dev.mysql.com/doc/refman/5.6/en/innodb-locks-set.html 

第一部分:概述

Myisam 的锁比较容易理解,无论是读还是写都只会加表锁,表锁又分为 read 锁和 write 锁,可以使用如下方式手动加锁:

– 加表锁语句(同样适用于 InnoDB):
lock tables
tbl_name [[AS] alias] lock_type
[, tbl_name [[AS] alias] lock_type] …
lock_type:
READ [LOCAL]
| [LOW_PRIORITY] WRITE
– 解表锁语句:
unlock tables
– 如何观察 InnoDB 锁:
set @@global.innodb_status_output_locks=on;
– 这样 show engine innodb status\G 可以显示额外的锁信息,标准情况下只显示锁数目。

由于 Myisam 这样的锁机制,导致 Myisam 是一款读性能较好,并发写性能较差的存储引擎,本文主要讨论如今的 MySQL 默认存储引擎 InnoDB 的锁机制。

第二部分:InnoDB 锁分类

InnoDB 存储引擎在使用到索引时会使用行锁,否则使用表锁。InnoDB 没有页锁,只有表锁和行锁。

一、InnoDB 表锁有以下几种:

S:就是在概述部分描述的表级 read 锁。

X:就是在概述部分描述的表级 write 锁。

IS:表级意向共享锁,即表示事务有向底层资源加共享行锁的意向。如 select … lock in share mode 语句,在加行锁之前会在表上现加 IS 锁,这样可以提高锁冲突检测的效率,同时也可以避免事务在表级添加会使其他事务行锁失效的表级锁。

IX:表级意向独占锁,即表示事务有向底层资源加独占行锁的意向。一般来说 delete、update 语句和 select … for update 语句都会在加行锁之前先加表级 IX 锁,除非未用到索引(此时直接加表级 X 锁)。

表锁的兼容性图:

MySQL 锁机制深入理解

此外表级锁还有一种比较特殊的锁:AUTO-INC Locks

这种锁只在向自增主键中插入记录时出现,由于自增主键在 MySQL 中较为常见,因此也算是经常会遇到的锁,这种锁是为自增主键设计的,无需和以上 4 钟锁检测冲突。

AUTO-INC Locks 的锁机制:

在向自增主键中插入记录时,其他 insert 事务都需要等待直到本事务的插入完成才能继续插入自增记录,注意是插入完成而不是本事务完成。这很好理解,因为需要保证自增主键的连贯性。但是如果你有超高的插入并发,那么肯定会带来性能问题。

因此 InnoDB 也提供了折中的方案,innodb_autoinc_lock_mode 参数可以控制你是否使用这种锁,如果你的自增主键不需要严格连贯而且需要更高的 insert 并发,那么可以禁用掉这种锁。

但是如果你做了主从复制,而且使用的是 statement 模式的 binlog,那么禁用 innodb_autoinc_lock_mode 后可能造成主从自增主键不一致,尤其是遇到 insert … select … from table_name; 这种语句。此时需要改为 row 模式或 mixed 模式的 binlog 主从复制,因为 row 模式对 SQL 执行顺序不敏感,而 mixed 模式也会将可能影响主从复制的 statement 改为 row 模式传输。

那么最后还有个问题就是既需要超高插入并发又需要连贯自增,那该怎么办?

凉拌~

二、InnoDB 行锁有以下四种:

1.Record lock

即在索引上加的锁,lock_mode 分为 S 和 X 两种模式。

例如 SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE; 就会 c1 列的索引上添加 S 类型的 Record lock。

Record lock 一定是加在索引记录上的,即便是一个没有定义任何索引的表,InnoDB 也会创建一个隐式的聚集索引,在用到此索引时加 Record lock。

2.Gap lock

即间隙锁,锁定不存在的索引记录,官方定义是:Gap lock 用于锁定 2 个索引记录之间、或第一个索引记录之前、或最后一个索引记录之后的范围。

通常我们会把 Record lock 和 Gap lock 合起来用,称为 Next-key lock,因此 Gap lock 就不多说了。

之所以设计 Gap lock 主要是为了解决幻读问题的,参考 SQL Server 的键范围锁。Gap 锁是可以禁用的,你可以将数据库的全局隔离级别设置为 read committed 或者将 innodb_locks_unsafe_for_binlog 参数设置为 1 来禁用 Gap lock,只是这样就会出现幻读,不过幻读一般并不是什么大问题,比如 Oracle 数据库的默认隔离级别下就无法避免幻读,不也大把人在用吗。

另外必须要说的一点是同一个 gap 上的 Gap lock 的 S 和 X 模式效果完全一样的,就算你加了一个 X 模式的 gap lock,其他事务也能在同一个 gap 上再加一个 X 模式的 gap lock,不会阻塞,当然仅限于同一个 gap。

3.Next-key lock

即 Record lock 和 Gap lock 的合体。例如 SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE; 会在 [10,20] 之间的 c1 index record 上加 lock_mode 为 X 的 next-key lock,也就是说会在 [10,20] 之间的所有存在的 index record 上加 X 模式的 record lock,同时也会用 X 模式的 gap 锁锁定不存在的 index record 防止幻读,这两种锁加起来就称作 next-key lock。

如果使用的索引是唯一索引,那么不加 next-key lock 的,只加 record lock。

再次提醒的是 next-key lock 其实并不存在而是 Record lock 和 Gap lock 的合体,show engine innodb status\G 显示的结果也都是用 Record lock 来展示的,不过展示出的数目比较诡异看不懂源码的话不建议深究,这点比 Oracle 和 Sqlserver 差太远。这里我就要顺带吐槽一下官网手册了,毕竟是开源 DB,一些前后矛盾和明显有歧义的解释也是让人很无奈。

4. 插入意向锁(Insert Intention Locks)

这个锁也是一个 InnoDB 的奇葩例子,不知道大家发现没 InnoDB 在谈 IX IS 还有行锁这些锁的时候基本不用 insert 语句来举例,这点如果是熟悉 Oracle 和 SQL Server 的人就会很困惑,因为增删改全都是 DML 语句,大家加锁机制基本相似的,无非就是表级意向锁 + 页级 or 行级锁的套路,但是 InnoDB 不是这样!!!insert 语句和 delete、update 完全不是一路人!!

这个锁用于表明:只要不是插入相同的 index record,多个事务向同一个 gap 插入记录是不会阻塞的。

插入意向锁其实是行级别的一种意向 gap 锁,既然有意向两字那么可以认定就是用于检测锁冲突的,是为在行级别获取 X 模式的 record lock 锁提前做检测。

用一个例子来解释更为明了:

– 会话 A 执行:
CREATE TABLE child (id int(11) NOT NULL, PRIMARY KEY(id)) ENGINE=InnoDB;
INSERT INTO child (id) values (90),(102);
START TRANSACTION;
SELECT * FROM child WHERE id > 100 FOR UPDATE;
– 会话 B 执行:
INSERT INTO child (id) VALUES (101);

可以看到会话 B 被阻塞了,而 show engine innodb status\G 看到的锁等待如下:

MySQL 锁机制深入理解

即 insert 语句想在 (90,102) 的 gap 上加个 lock_mode= X 的 gap 锁,也就是 Insert Intention Lock,但是会话 A 的 select for update 语句已经在 (100,102) 的 gap 上添加了 X 模式的 gap 锁,这是一个与 (90,102) 不同但被包含在内的 gap,于是被阻塞无法获取 X 模式的 Insert Intention Gap Lock。

三、总结

MySQL 的锁机制基本就如上所示了,但是了解 InnoDB 锁只是初步的,还必须结合事务隔离级别的概念去判断各种 SQL 的具体加锁机制,因为事务隔离级别会影响 SQL 的默认加锁模式。

MySQL 的事务隔离级别定义也是遵循 ANSI SQL92 标准的,不过但凡是家数据库厂商都会说自己遵循 SQL92 标准,而事实是早已加料加的面目全非。当然这全都是为了能够提供更好的并发性能。例如 Oracle 也说自己遵循 SQL92 标准,结果四大隔离级别只支持 2 个,SQL Server 也说自己支持,结果又多造出来 2 个事务隔离级别。

同样的 MySQL 也提供了 4 大基本的事务隔离级别,不同的隔离级别下加锁机制区别很大,将在另一篇笔记中详述。

本文永久更新链接地址:https://www.linuxidc.com/Linux/2018-04/151914.htm

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-22发表,共计3893字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中

星哥玩云

星哥玩云
星哥玩云
分享互联网知识
用户数
4
文章数
19351
评论数
4
阅读量
7989056
文章搜索
热门文章
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
我把用了20年的360安全卫士卸载了

我把用了20年的360安全卫士卸载了

我把用了 20 年的 360 安全卫士卸载了 是的,正如标题你看到的。 原因 偷摸安装自家的软件 莫名其妙安装...
再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见 zabbix!轻量级自建服务器监控神器在 Linux 的完整部署指南 在日常运维中,服务器监控是绕不开的...
飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛 NAS 中安装 Navidrome 音乐文件中文标签乱码问题解决、安装 FntermX 终端 问题背景 ...
阿里云CDN
阿里云CDN-提高用户访问的响应速度和成功率
随机文章
星哥带你玩飞牛NAS-7:手把手教你免费内网穿透-Cloudflare tunnel

星哥带你玩飞牛NAS-7:手把手教你免费内网穿透-Cloudflare tunnel

星哥带你玩飞牛 NAS-7:手把手教你免费内网穿透 -Cloudflare tunnel 前言 大家好,我是星...
星哥带你玩飞牛NAS硬件02:某鱼6张左右就可拿下5盘位的飞牛圣体NAS

星哥带你玩飞牛NAS硬件02:某鱼6张左右就可拿下5盘位的飞牛圣体NAS

星哥带你玩飞牛 NAS 硬件 02:某鱼 6 张左右就可拿下 5 盘位的飞牛圣体 NAS 前言 大家好,我是星...
安装并使用谷歌AI编程工具Antigravity(亲测有效)

安装并使用谷歌AI编程工具Antigravity(亲测有效)

  安装并使用谷歌 AI 编程工具 Antigravity(亲测有效) 引言 Antigravity...
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
CSDN,你是老太太喝粥——无齿下流!

CSDN,你是老太太喝粥——无齿下流!

CSDN,你是老太太喝粥——无齿下流! 大家好,我是星哥,今天才思枯竭,不写技术文章了!来吐槽一下 CSDN。...

免费图片视频管理工具让灵感库告别混乱

一言一句话
-「
手气不错
星哥带你玩飞牛NAS-13:自动追番、订阅下载 + 刮削,动漫党彻底解放双手!

星哥带你玩飞牛NAS-13:自动追番、订阅下载 + 刮削,动漫党彻底解放双手!

星哥带你玩飞牛 NAS-13:自动追番、订阅下载 + 刮削,动漫党彻底解放双手! 作为动漫爱好者,你是否还在为...
浏览器自动化工具!开源 AI 浏览器助手让你效率翻倍

浏览器自动化工具!开源 AI 浏览器助手让你效率翻倍

浏览器自动化工具!开源 AI 浏览器助手让你效率翻倍 前言 在 AI 自动化快速发展的当下,浏览器早已不再只是...
开源MoneyPrinterTurbo 利用AI大模型,一键生成高清短视频!

开源MoneyPrinterTurbo 利用AI大模型,一键生成高清短视频!

  开源 MoneyPrinterTurbo 利用 AI 大模型,一键生成高清短视频! 在短视频内容...
一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸

一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸

一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸 前言 作为天天跟架构图、拓扑图死磕的...
每年0.99刀,拿下你的第一个顶级域名,详细注册使用

每年0.99刀,拿下你的第一个顶级域名,详细注册使用

每年 0.99 刀,拿下你的第一个顶级域名,详细注册使用 前言 作为长期折腾云服务、域名建站的老玩家,星哥一直...