前阿里数据库专家总结的MySQL里的各种锁(上篇)
0.前言
MySQL按照加锁的范围,分为全局锁、表级锁、行级锁。
本文作为上篇,主要介绍MySQL的全局锁 和 表级锁。
重要的实战总结为,如何安全地变更一个表的表结构。
1.全局锁
定义:
全局锁就是对整个数据库实例加锁。
全局锁语法:
Flush tables with read lock (FTWRL)
当你使用这个命令后,整个库处于只读状态,之后其他线程的数据更新语句(DML)、数据定义语句(DDL)都会被阻塞。
场景:不支持事务的引擎(如MyISAM),做全库的逻辑备份。
不过我们一般使用innodb,这个锁不太会接触,就不展开详细介绍了。
2.表级锁
表级锁其实有两种,一种叫表锁,一种叫原数据锁(meta data lock, MDL)
2.1 表锁
表锁的语法是:
锁表:lock tables … read/write
释放锁: unlock tables 主动释放锁
表锁也能够在客户端断开的时候自动释放。
值得注意的是,lock tables 除了会限制别的线程的读写外,当前线程接下来的操作也会被限制。
同样的,对于innoDB这种支持行锁的引擎,我们一般也不会去使用用表锁,因此,这部分内容也只需要简单了解下即可。
2.2 MDL锁
原数据锁meta data lock 也是一种表级锁,在 MySQL 5.5 版本中引入。
当我们对一个表做CRUD操作的时候,会加 MDL 读锁;当要对表做结构变更操作的时候,加 MDL 写锁。
MDL读写锁的互斥
- 读锁之间不互斥,所以我们可以有多个线程同时对一张表增删改查。
- 读锁和写锁之间、写锁和写锁之间是互斥的,用来保证变更表结构操作的安全性。因此,只要有一个线程要对一个表加字段,那天其他线程必须等这个线程完成表结构变更以后才能执行。
看到这里,不得不给大家举例一个日常会踩的坑。
对于大表DDL,大家一般比较谨慎,而对于小表,就会比较随意。但是小表DDL也能造成数据库崩溃。
Session A第一个启动,开启事务,select后没有立刻commit,模仿一个长事务,此时,session A对表tt的MDL读锁还没有释放。
Session B之后执行一个select,由于MDL读锁之间不互斥,因此执行成功。
Session C之后想对表tt 执行一个alter语句,需要获得MDL写锁,但是由于Session A持有了MDL读锁,读写锁互斥,因此Session C被阻塞。
Session D这时候也想执行一个select,由于Session C被阻塞,所以Session D也会被阻塞。
所以这个时候,后续的线程就都无法读写了。
如果接下来这个表上有频繁的查询,而且客户端有重试机制,那么超时后会再起一个新的session来查询,很快数据库的线程就溢出了。
这里有几个小问题需要稍微再解释一下:
1)从Session A的情况我们得知,事务中 的MDL锁,在语句开始时申请,但是并不是在语句结束后马上释放的,而是在整个事务提交后才会释放。
2)SessionC(DDL操作)被前面的SessionA和B(查询操作,获取MDL 读锁)所阻塞,这里实际上并没有成功获取MDL写锁,为什么Session D的读操作会被sessionC所阻塞呢?这里的原因是,MySQL Server端,对于Session C和Session D会有一个队列来决定谁先执行。
看到这里,我相信肯定有对MySQL比较熟悉的朋友会问了,MySQL 5.6不是号称支持Online DDL吗?怎么这里又会有各种阻塞呢?
首先,我们先明确下什么叫做Online DDL。
Online DDL的过程中,对于锁的获取分为五步(具体online DDL过程比较复杂,本文不展开说明):
1)拿到MDL写锁
2)降级成MDL读锁
3)真正做DDL
4)升级成MDL写锁
5)释放MDL锁
1、2、4、5如果没有锁冲突,执行时间都是非常短的。绝大部分时间是第三步占用了,而这个期间,表可用正常读写,所以被称为Online DDL。
而我们上文的例子,实际上是在第一步就阻塞了。
3.So,如何做一次安全的表结构变更
其实,无论大表小表的表结构变更,都应用引起我们重视。
总结了上文,大家应该都知道了最关键的三点:
避免长事务!
避免长事务!
避免长事务!
尤其是在执行表结构变更前,可以在information_schema库的innodb_trx表中,查看当前执行的事务。如果有长事务正在执行,要延迟等待执行变更,或者手动先kill长事务。
另外,尽量保证表结构变更在数据库流量低峰期操作,比如夜间,这样能更好地避免出现风险。
所以,如何做一次安全的表结构变更?
1)避免长事务
2)在流量低峰进行
就是这么简单。
下一期,我们就好好聊聊 行锁,不见不散~
参考:
丁奇《MySQL 实战45讲》
看到这里了,原创不易,点个关注、点个赞吧,你最好看了~
知识碎片重新梳理,构建Java知识图谱:https://github.com/saigu/JavaKnowledgeGraph(历史文章查阅非常方便)
扫码关注我的公众号“阿丸笔记”,第一时间获取最新更新。同时可以免费获取海量Java技术栈电子书、各个大厂面试题。

前阿里数据库专家总结的MySQL里的各种锁(上篇)的更多相关文章
- 前阿里数据库专家总结的MySQL里的各种锁(下篇)
在上篇中,我们介绍了MySQL中的全局锁和表锁. 今天,我们专注于介绍一下行锁,这个在日常开发和面试中常常困扰我们的问题. 1.行锁基础 由于全局锁和表锁对增删改查的性能都会有较大影响,所以,我们自然 ...
- 数据库性能测试---前阿里数据库团队资深DBA杨奇龙
杨奇龙 前阿里数据库团队资深DBA 主要负责淘宝业务线,经历多次11.11,有海量业务访问DB架构设计经验. 目前就职于有赞科技DBA,负责数据库运维工作,熟悉MySQL 性能优化,故障诊断,性能压测 ...
- MySQL里面的锁
MySQL里面的锁可以分为:全局锁,表级锁,行级锁. 一.全局锁:对整个数据库实例加锁.MySQL提供加全局读锁的方法:Flush tables with read lock(FTWRL)这个命令可以 ...
- 重新定义数据库的时刻,阿里云数据库专家带你了解POLARDB
摘要:POLARDB是阿里云ApsaraDB数据库团队研发的基于云计算架构的下一代关系型数据库,其最大的特色是计算节点与存储节点分离,借助优秀的RDMA网络以及最新的块存储技术.POLARDB不但满足 ...
- 重新学习MySQL数据库10:MySQL里的那些日志们
重新学习MySQL数据库10:MySQL里的那些日志们 同大多数关系型数据库一样,日志文件是MySQL数据库的重要组成部分.MySQL有几种不同的日志文件,通常包括错误日志文件,二进制日志,通用日志, ...
- jdbc连接阿里云服务器上的MySQL数据库 及 数据库IP限制
问题1:Jdbc 如何连接阿里云服务器上的MySQL数据库? 解决: 上截图: 其中IP是阿里云服务器的公网IP地址. 问题2: 刚开始接手开发的时候,使用Navicat连接阿里云服务器上的数据后 ...
- mysql里的数据库引擎, 编码格式
针对数据库里即使设置了varchar类型的字段, 值输入中文报错的情况,是因为数据库的默认编码类型不支持汉字输入. utf-8 可以编译全球通用的所有语言符号. 由1-6个可变字节组成,有非常严格的排 ...
- 使用Navicat连接阿里云服务器上的MySQL数据库=======Linux 开放 /etc/hosts.allow
使用Navicat连接阿里云服务器上的MySQL数据库 1.首先打开Navicat,文件>新建连接> 2,两张连接方法 1>常规中输入数据库的主机名,端口,用户名,密码 这种直接 ...
- 云栖神侠传—阿里云数据库专家德歌告诉你PostgreSQL的那些事
什么是云栖神侠传: 云栖社区(http://yq.aliyun.com/?utm_source=yqdg),是阿里云面向开发者群体的开放型社区.在云栖社区中,活跃着许多阿里技术大牛,他们在自己的技术领 ...
随机推荐
- NOIP 2004 T3 合唱队形(DP、最长上升/下降子序列)
链接:https://ac.nowcoder.com/acm/contest/1082/C来源:牛客网 题目描述 N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队 ...
- IMX6Q开发板Linux-QT挂载U盘及TF卡
本文基于:迅为-iMX6开发板Linux-QT挂载U盘及TF卡 如下图所示,qt 启动之后,在超级终端中使用命令“mknod /dev/sda1 b 8 1”创建 U盘的设备节点,如下图所示. 插入 ...
- 如何查看Linux系统下程序运行时使用的库?
Linux系统下程序运行会实时的用到相关动态库,某些场景下,比如需要裁剪不必要的动态库时,就需要查看哪些动态库被用到了. 以运行VLC为例. VLC开始运行后,首先查看vlc的PID,比如这次查到的V ...
- pip install torch出现错误
首先使用Python的pip安装命令: pip install torch 出现错误 解决办法:这时需要先下载pytorch包,根据自己的python版本选择.pytorch包链接: https:// ...
- Yii框架的学习指南(策码秀才篇)1-1 如何认识Yii framework
Yii的框架和其他框架的区别在于:它是更加 快速,安全,专业的PHP框架 Yii是一个高性能的,适用于开发WEB2.0应用的PHP框架. Yii是一个基于组件.用于开发大型 Web 应用的 高性能 P ...
- Zabbix 监控sqlserver
转:Zabbix 监控sqlserver 一:Zabbix监控sqlserver 方法一: 1.思路整理 1.在zabbix server上安装Freetds.unixODBC.unixODBC-de ...
- [LC] 244. Shortest Word Distance II
Design a class which receives a list of words in the constructor, and implements a method that takes ...
- Qt5 提示:无法启动此程序,计算机丢失Qt5Widgetsd.dll的解决方法
Qt5工程编译生成可执行的exe文件之后,运行提示无法启动此程序,计算机丢失Qt5Widgetsd.dll… 原因是没有设置好Qt5的环境变量,解决方法如下: 1.打开[环境变量],(不同的系统会有不 ...
- .net批量插入数据库,SqlBulkCopy方法
/// <summary> /// 把数据插入LessonQuestion表 /// </summary> /// <param name="lessontit ...
- js 实现排序算法 -- 快速排序(Quick Sort)
原文: 十大经典排序算法(动图演示) 快速排序 快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整 ...