Mysql 中的MDL
本文可以结合 MySQL中的事务原理和锁机制 查看。
首先简单了解一下 mysql 的 sql 类型:
1、数据定义语言 DDL:Create、Drop、Alter 操作。用于定义库和表结构的。
2、数据查询语言 DQL:select。用于查询数据的。
3、数据操纵语言 DML:insert、update、delete。对行记录进行增删改操作。
4、数据控制语言 DCL:grant、revoke、commit、rollback。控制数据库的权限和事务。
MDL
MDL(MetaData Lock)就是针对于 DDL 与 DML、DQL 操作加锁,执行 DDL 自动添加写锁,执行 DML、DQL 自动添加读锁,也就是说 DML 语句可以同时执行(不考虑其他锁),而 DDL 间则会相互阻塞。
为什么在执行 DDL 时会添加写锁?
DDL 在执行会先创建一个临时表,先将表的数据全部移到这个临时表中,然后再将临时表替换当前表。在这个过程中如果出现读写操作就会影响最终结果出错。这个过程耗时主要在将原表的数据移到临时表的过程。
执行
不同事务的执行是按队列顺序进行的,如果两个事务所执行的 MDL 添加的分别是读、写锁,那么就会互斥,后面的事务只有等到前面事务提交释放锁后才能执行。
例子:假设有四个会话:session1、session2、session3、session4 ,首先先依次开启事务,然后session1,session2 先执行查询操作(为了避免可能是可串行化级别导致加的写锁冲突,所以就使用查询操作),session1,session2 中的操作可以正常执行,session3执行 Alter 修改表结构,此时 session3 的操作就会阻塞(因为 MDL 的读写锁冲突),session4 再执行增删改查也会被阻塞,因为是在队列中,它位于 session3 后面,所以只有等到 session3 提交后其才能继续执行。
Online DDL
通过上面的分析,进行实践检验,却出现了下面的情况:
可以看到执行和显示顺序是图中标注的从1开始递增按顺序执行的。可以看到 session4 在 session2 提交后就立刻会执行,并且在 session4 提交后 session3 才能执行成功,这个和前面所说的理论就会冲突。这个原因是当前 mysql 版本是5.6,而在 mysql 5.6 支持 Online DDL。
Online DDL 是对 MDL 的一种优化,因为如果按照 MDL 的执行逻辑,像上面这种情况,一旦一些简单的读写操作比某一条 DDL 语句启动慢一些,就会陷入阻塞,如果 DDL 修改的是大表且是高频表,那么在这条语句执行时会阻塞所有的读写操作,很容易使数据库崩溃。而 Online DDL 优化思路就是在获取到锁之后先允许一段时间的读写操作,直到临时表的数据转移完成,再停止其他读写操作,而具体实现就主要分为下面几步,
1. 拿MDL写锁
2. 降级成MDL读锁,接受读写操作,读操作直接正常返回,写操作会被记录下来,等待后面更新到临时表中。
3. 真正做DDL,在 DDL 表记录向临时表转移完成并执行完记录的写操作后开始阻塞读写操作。
4. 升级成MDL写锁,进行临时表的替换
5. 释放MDL锁
应用于上面的例子就是:
1、session1、session2 因为是队列的前两个,先添加MDL读锁,正常执行,session3 因为是要添加 MDL 写锁所以阻塞,session4 在 session3 后面所以也阻塞,session1、session2执行完成提交释放读锁。
2、session3 在获取到 MDL 写锁后,会先进行降级降级成读锁
3、在 session3 降级后 session4 因为是 MDL 读锁,所以也会获取到锁,执行
4、session3 在完成向临时表数据迁移以及执行完记录的写操作后想升级回写锁发现当前的读锁还被 session4 占用,所以会阻塞,等待 session4 执行释放。
5、session4 提交事务,释放读锁,session3 成功升级锁,输出提示语句,最后提交。
如果前面的例子还有一个 session5,并且在一开始和 session4 一起开启事务、查询,那么在 session2 提交后 session5 也会随着 session4 一起执行,而 session3 则需要等待 session4、session5 提交后才能执行第四步。
而如果 session5 开启事务是在 session3 向临时表数据迁移完成后,那么 session5 的查询操作就会被 session3 阻塞,直到 session3 提交事务。
MDL 引发的问题
在上线项目中,如果需要对某个大表的字段进行删除,那么必然会阻塞该表的所有增删改查操作,如果该表存储了热点数据,那么就会阻塞大量的操作,最终导致数据库崩溃。
解决
1、查看当前是否存在长事务,如果存在,先尽快将其提交,防止长事务的MDL写锁阻塞
2、为 DDL 的操作设置过期时间,如果时间内没有成功执行就取消。可以使用 Github 的开源工具 gh-ost。
Mysql 中的MDL的更多相关文章
- MySQL · 特性分析 · MDL 实现分析
http://mysql.taobao.org/monthly/2015/11/04/ 前言 在MySQL中,DDL是不属于事务范畴的,如果事务和DDL并行执行,操作相关联的表的话,会出现各种意想不到 ...
- MySQL实战 | 06/07 简单说说MySQL中的锁
原文链接:MySQL实战 | 06/07 简单说说MySQL中的锁 本文思维导图:https://mubu.com/doc/AOa-5t-IsG 锁是计算机协调多个进程或纯线程并发访问某一资源的机制. ...
- 你了解MySQL中的锁吗?
MySQL中的锁,分为全局锁.表级锁.行锁 全局锁 全局锁的意思就是,对整个数据库实例加锁,它的命令是FTWRL Flash tables with read lock 这个命令的语义是,使整个库处于 ...
- 一步一步带你入门MySQL中的索引和锁 (转)
出处: 一步一步带你入门MySQL中的索引和锁 索引 索引常见的几种类型 索引常见的类型有哈希索引,有序数组索引,二叉树索引,跳表等等.本文主要探讨 MySQL 的默认存储引擎 InnoDB 的索引结 ...
- Mysql中的三类锁,你知道吗?
导读 正所谓有人(锁)的地方就有江湖(事务),人在江湖飘,怎能一无所知? 今天来细说一下Mysql中的三类锁,分别是全局锁.表级锁.行级锁. 文章首发于作者公众号[码猿技术专栏],原创不易,喜欢的点个 ...
- 【科普】MySQL中DDL操作背后的并发原理
一. 简介 DQL:指数据库中的查询(select)操作. DML:指数据库中的插入(insert).更新(update).删除(delete)等行数据变更操作. DDL:指数据库中加列(add co ...
- 详述 MySQL 中的行级锁、表级锁和页级锁
转自:https://blog.csdn.net/qq_35246620/article/details/69943011 refer:cnblogs.com/f-ck-need-u/p/899547 ...
- MySQL 中如何定位 DDL 被阻塞的问题
经常碰到开发.测试童鞋会问,线下开发.测试环境,执行了一个DDL,发现很久都没有执行完,是不是被阻塞了?要怎么解决? 包括在群里,也经常会碰到类似问题:DDL 被阻塞了,如何找到阻塞它的 SQL ? ...
- MySQL中You can't specify target table for update in FROM clause一场
mysql中You can't specify target table <tbl> for update in FROM clause错误的意思是说,不能先select出同一表中的某些值 ...
随机推荐
- 一看就懂的:MySQL数据页以及页分裂机制
文章公号 首发!连载中~ 欢迎各位大佬关注, 回复:"抽奖" 还可参加抽活动 文末有二维码 一.知识回顾 回顾一下之前和大家分享的知识点 看了前面的文章,想必你肯定了解了什么是Bu ...
- python搭建本地共享文件服务器
1.安装python 去官网下载python最新版,然后安装配置好环境 2.运行命令 在终端上输入以下命令 python3 -m http.server 当你执行完这个命令的时候,你的电脑会监听 80 ...
- T - Permutation 题解(思维+dp)
题目链接 题目大意 给你一个数字n和长为n-1个字符串 字符串包含'<','>' 若s[i]='<' 则代表a[i]<a[i+1] 若s[i]='>' 则代表a[i]&g ...
- .Net Core官方的 JWT 授权验证
什么是JWT? JSON Web令牌(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间安全地传输信息作为JSON对象.由于此信息是经过数字签名的,因此可以被验 ...
- Mellanox 4036配置
1.前言 内置factory-default 会重置所有参数到出厂设置. 内置reboot.拔电源就是重启. 外置reset就是重置芯片中数据,不会恢复到出厂设置. 2.感受下恢复出厂过程 4036- ...
- PyQt学习随笔:ListView控件的视图和数据模型分离案例
Qt 中view类控件的目的是实现数据和模型分离,控件展示数据,数据保存在数据存储中,数据存储中的数据改变了,则控件中展示的数据跟随改变.当设计时只指定了一个控件和一个数据存储关联时,这种分离虽然也能 ...
- 孪生网络入门(下) Siamese Net分类服装MNIST数据集(pytorch)
主题列表:juejin, github, smartblue, cyanosis, channing-cyan, fancy, hydrogen, condensed-night-purple, gr ...
- C# Email 帮助类 EmailHelper
1. 配置文件 App.config <?xml version="1.0" encoding="utf-8" ?> <configurati ...
- Java IO源码分析(二)——ByteArrayInputStream 和 ByteArrayOutputStream
简介 ByteArrayInputStream 是字节数组输入流,它继承于InputStream. 它的内部数据存储结构就是字节数组. ByteArrayOutputStream是字节数组输出流,它继 ...
- Spring 中常用的注解
(1).用于注册bean对象的注解 1.1@Component: 作用: 调用无参构造创建一个bean对象,并把对象存入spring的Ioc容器,交由spring容器进行管理.相当于在xml中配置一个 ...