前阿里数据库专家总结的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),是阿里云面向开发者群体的开放型社区.在云栖社区中,活跃着许多阿里技术大牛,他们在自己的技术领 ...
随机推荐
- iOS之input file调用相册控制器消失跳转到登陆页
最近在做一个app要用到H5,其中有一个需求是要点击H5的的控件弹出系统相册,通过在H5的input file 中定义<input type="file" class=&qu ...
- mysql免安装版 win10
1.在官网中下载免安装版:https://dev.mysql.com/downloads/mysql/ 2.解压下载后的文件,新建 data 文件夹和 my.ini 文件 3.打开 my.ini 文 ...
- rest framework-restful介绍-长期维护
############### django框架-rest framework ############### # django rest framework 框架 # 为什么学习这个res ...
- android应用市场、社区客户端、漫画App、TensorFlow Demo、歌词显示、动画效果等源码
Android精选源码 MVP架构Android应用市场项目 android刻度盘控件源码 Android实现一个社区客户端 android商品详情页上拉查看详情 基于RxJava+Retrofit2 ...
- JVM如何判断对象能否被回收
•写在前面说起Java和C++,很容易想到让人疯狂的指针,Java使用了内存动态分配和垃圾回收技术,让我们从C++的各种指针问题中摆脱出来,更加专心于业务逻辑,不过如果我们需要深入了解java的JVM ...
- yum命令不能使用的解决办法
以前yum命令一直是可用的,今天使用它安装命令时一直提示,如下图: 百度了一圈说是网络问题: 然后我就ping www.baidu.com 可以ping通啊 最后在同事的帮助下找到了解决办法: vi ...
- Tmux 速成教程:技巧和调整
本文转自:http://blog.jobbole.com/87584/ 简介 有些开发者经常要使用终端控制台工作,导致最终打开了过多的标签页.如果你也是他们当中的一员,或者你正在实践结对编程,那么我推 ...
- 微信发送朋友圈URL JSAPI事件demo
<script> var imgUrl = 'http://m.ximiyu.com/content/images/thumbs/0000126_540.jpeg'; var lineLi ...
- 全文检索ElasticSearch的简单使用笔记
工具:kibana GET _search { "query": { "match_all": {} } } #创建索引结构 PUT sku { "m ...
- 饿了么vue实现学习笔记
技术栈:vue2 + vuex + vue-router + webpack + ES6/7 + fetch + sass + flex + svg以功能实现着手学习1. 定位功能 home.vue ...