mysql-MDL元数据锁
表级锁 MDL(metadata lock)。
1、介绍
2、加锁:MDL 不需要显式使用,在访问一个表的时候会被自动加上。
3、作用:保证读写的正确性。(你可以想象一下,如果一个查询正在遍历一个表中的数据,而执行期间另一个线程对这个表结构做变更,删了一列,那么查询线程拿到的结果跟表结构对不上,肯定是不行的)
4、使用:在 MySQL 5.5 版本中引入了 MDL,当对一个表做增删改查操作的时候,加 MDL 读锁;当要对表做结构变更操作的时候,加 MDL 写锁。读锁之间不互斥,因此你可以有多个线程同时对一张表增删改查。读写锁之间、写锁之间是互斥的,用来保证变更表结构操作的安全性。因此,如果有两个线程要同时给一个表加字段,其中一个要等另一个执行完才能开始执行。
5、踩坑:给一个小表加个字段,导致整个库挂了。
你肯定知道,给一个表加字段,或者修改字段,或者加索引,需要扫描全表的数据。在对大表操作的时候,你肯定会特别小心,以免对线上服务造成影响。而实际上,即使是小表,操作不慎也会出问题。我们来看一下下面的操作序列,假设表 t 是一个小表。备注:这里的实验环境是 MySQL 5.6。
我们可以看到 session A 先启动,这时候会对表 t 加一个 MDL 读锁。由于 session B 需要的也是 MDL 读锁,因此可以正常执行。之后 session C 会被 blocked,是因为 session A 的 MDL 读锁还没有释放,而 session C 需要 MDL 写锁,因此只能被阻塞。如果只有 session C 自己被阻塞还没什么关系,但是之后所有要在表 t 上新申请 MDL 读锁的请求也会被 session C 阻塞。前面我们说了,所有对表的增删改查操作都需要先申请 MDL 读锁,就都被锁住,等于这个表现在完全不可读写了。如果某个表上的查询语句频繁,而且客户端有重试机制,也就是说超时后会再起一个新 session 再请求的话,这个库的线程很快就会爆满。你现在应该知道了,事务中的 MDL 锁,在语句执行开始时申请,但是语句结束后并不会马上释放,而会等到整个事务提交后再释放。
6、填坑
给小表加字段:
(1)首先我们要解决长事务,事务不提交,就会一直占着 MDL 锁。在 MySQL 的 information_schema 库的 innodb_trx 表中,你可以查到当前执行中的事务。如果你要做 DDL 变更的表刚好有长事务在执行,要考虑先暂停 DDL,或者 kill 掉这个长事务。
(2)如果你要变更的表是一个热点表,虽然数据量不大,但是上面的请求很频繁,而你不得不加个字段,你该怎么做呢?这时候 kill 可能未必管用,因为新的请求马上就来了。
比较理想的机制是,在 alter table 语句里面设定等待时间,如果在这个指定的等待时间里面能够拿到 MDL 写锁最好,拿不到也不要阻塞后面的业务语句,先放弃。之后开发人员或者 DBA 再通过重试命令重复这个过程。
执行语法为alter table table_nam wait 10 add cloumn
给大表加字段:
使用三方工具(gh-ost和pt-online-schema-change)参考: https://developer.aliyun.com/article/929999
原理:
(1)新建一模一样的表,表名可以起为_new后缀
(2)接着在这个新表执行更改字段操作
(3)接着在原表上加三个触发器,分别为delete、update、insert,将原表中要执行的语句也在新表中执行
(4)最后将原表的数据拷贝到新表中,替换掉原表
7、实战
show processList
id:为session_id,也就是processlist_id
user:该session使用什么用户登陆的mysql数据库
host:客户端登陆的ip地址(这里我都是本地登陆的)
db:连接了哪个数据库(这里我只是连接上了数据库,并没有其他操作,所以都是NULL)
command:当前session执行命令的类型
Time:处于当前命令类型持续的时间
State:当前命令类型的状态
Info:具体命令信息
8、总结
产生元数据锁的原因:
数据锁是server层的锁,表级锁,主要用于隔离DML和DDL操作之间的干扰。每执行一条DML、DDL语句时都会申请MDL锁,DML操作需要MDL读锁,DDL操作需要MDL写锁(MDL加锁过程是系统自动控制,无法直接干预,读读共享,读写互斥,写写互斥),申请MDL锁的操作会形成一个队列,队列中写锁获取优先级高于读锁。一旦出现写锁等待,不但当前操作会被阻塞,同时还会阻塞后续该表的所有操作。事务一旦申请到MDL锁后,直到事务执行完才会将锁释放。(这里有种特殊情况如果事务中包含DDL操作,mysql会在DDL操作语句执行后,隐式提交commit,以保证该DDL语句操作作为一个单独的事务存在,同时也保证元数据排他锁的释放,例如id 44的语句改为<begin;alter table testok add z varchar(10) not Null;select * from testok;>,此时一旦alter语句执行完成会马上提交事务(autocommit=1),后面的select就在本次事务之外,其执行完成后不会持有读锁)
mysql-MDL元数据锁相关推荐
- mysql mdl 锁_详细分析mysql MDL元数据锁
前言: 当你在MySQL中执行一条SQL时,语句并没有在你预期的时间内执行完成,这时候我们通常会登陆到MySQL数据库上查看是不是出了什么问题,通常会使用的一个命令就是 show processlis ...
- 深入理解MDL元数据锁
前言: 当你在MySQL中执行一条SQL时,语句并没有在你预期的时间内执行完成,这时候我们通常会登陆到MySQL数据库上查看是不是出了什么问题,通常会使用的一个命令就是 show processlis ...
- MySQL的元数据锁MDL发生场景和解决方法总结
摘要 MetaData Lock即元数据锁,在数据库中元数据即数据字典信息包括db,table,function,procedure,trigger,event等.Metadata lock主要为了保 ...
- MySQL的MDL元数据锁
一 序 本来在看mysql.taobao介绍InnoDB 事务子系统介绍 ,真的头大,名词都看不懂,还是分开来学习的好,本文主要整理MDL(metadata locking)锁.作为尝试学习人新人,发 ...
- mysql MDL锁如何解决_理解MySQL的MDL元数据锁
一.MDL锁的作用 MySQL DBA 对于 Waiting for table metadata lock 肯定不会陌生,一般都是进行 alter 操作时被堵住了,导致了我们在 show proce ...
- 【MySQL】MySQL 数据库表锁和行锁
文章目录 1.概述 1. 全局锁 1.1. 全局锁的特点 1.2. 全局锁的作用(全库逻辑备份) 2.表级锁 2.1. 表锁 2.1.1. 特点 2.2. MDL元数据锁(metadata lock) ...
- mysql5.7官网直译锁操作优化--并发添加,元数据锁,外部闭锁
8.11.3 Concurrent Inserts 并发插入 MyISAM存储引擎支持并发插入从而来减少对读写对给出表的竞争:如果一张MyISAM表的数据文件没有漏洞存在(也就是在表中删除了中间的行) ...
- mysql MDL锁如何解决_MySQL元数据锁MDL
[TOC] > 除了我们经常熟知的共享锁和排他锁外,MySQL数据库还有一种锁叫元数据锁,主要为了保证元数据的一致性,用于处理不同线程操作同一数据对象的同步与互斥问题. # 一.元数据 所谓元数 ...
- 【华为云技术分享】华为云MySQL新增MDL锁视图特性,快速定位元数据锁问题
MDL锁(Metadata Lock),即元数据锁.元数据指的是描述数据的数据,对数据及信息资源的描述性信息,在数据库中元数据即数据字典信息,包括db,table,function,procedure ...
- MySQL 元数据锁(MDL)
前言: 当我们在 MySQL 中执行 DDL 语句时,经常会发现语句没有在你预期的时间完成,这时候我们通常会在mysql输入终端输入show full processlist ,来看看发生了什么状况. ...
最新文章
- python 匿名函数的使用
- 计算机基础知识与基本操作txt,计算机基础知识复习-20210707023705.pdf-原创力文档...
- 8.正交匹配跟踪 Orthogonal Matching Pursuit (OMP)s
- 注入游戏没有焦点_数独游戏 数学之美(三)
- 重磅!2021 高通人工智能应用创新大赛今日开赛
- 企业shell面试题:获取51CTO博客列表按时间倒序排序
- dlopen函数的用法
- P2782 友好城市
- c语言做一个小程序报告,《C语言程序设计实践》课程报告30个小程序组合成一个大程序.doc...
- 批处理框架 Spring Batch,数据迁移量过大如何保证内存?
- 系统运行后修改linux系统时区
- 实现有管理功能的ASP留言板
- 织梦程序添加音乐上传功能
- 如何通俗理解EM算法
- 企业员工管理系统(java实现版)
- 校招网工面试经历(持续更新)
- 扩展RBAC用户角色权限设计方案(转载)
- 两轮车燃油喷射系统的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
- 各位亲朋好友新春大吉
- HTML5,js制作坦克大战