王小川|MySQL强人“锁”难《死磕MySQL系列 三》( 三 )
回答是:“MDL 是在事务提交后才会释放 , 这意味着事务执行期间 , MDL 是一直持有的 。 ”
那么看一个场景 。
首先 , 线程A开启事务并执行查询语句时 , 对表加上了MDL锁 。
然后 , 线程B执行的是查询 , 并不会堵塞住 , 因为读与读并不冲突 。
接着 , 线程C修改表结构 , 此时的线程A还未提交事务 , MDL还未释放 , 这时的线程因无法获取到MDl写锁 , 就会被阻塞 。
最后线程D执行查询会发生什么呢?
答案是堵塞 。
【王小川|MySQL强人“锁”难《死磕MySQL系列 三》】到这里按照正常的逻辑 , 线程C没有获取到MDL的写锁 , 线程D是可以申请到MDL读锁的 , 那为什么还会堵塞呢!
这是因为申请MDL锁的操作会形成一个队列 , 队列中写锁获取优先级高于读锁 , 一旦出现MDL写锁等待 , 会阻塞后续该表的所有CURL操作 。
到这里你有没有后背发凉 , 一旦你在一个未提交事务之后执行了DDL操作 , 那么等到的结果就是MySQL挂掉 , 客户端会有重试机制 , DDL后所有CURD会在超时后重新发起请求 , 这个库的线程会很快爆满 。
既然这样如何给表安全的执行DDL操作呢?
首先 , 必须解决到长事务 , 事务不提交MDL锁就无法释放 。
然后 , 在MySQL系统表里找到infomation_schema库中的innodb_trx , 可以查看当前正在执行中的事务ID , 这个表在事务那期文章中也没少提 。
接着 , 你是不是想kill掉这些长事务然后执行DDL不就得了 。
试想一下 , 当你kill掉的下一刻一个新的事务又进来了 , 同时你又执行了DDL操作 , 后果是什么应该清楚了哈!这种操作肯定是不行的 。
官方大大怎么会允许这种情况发生呢!
于是当你执行DDL操作时alter table kaka wait 30 add name可以加一个等待时间 , 如果在这个等待时间拿到MDL写锁最好 , 拿不到也不能堵塞后边的业务逻辑 , 先放弃 。 再重试执行这个命令 。
四、总结
坚持学习、坚持写作、坚持分享是咔咔从业以来所秉持的信念 。 愿文章在偌大的互联网上能给你带来一点帮助 , 我是咔咔 , 下期见 。
- 在昨日推文中,王者荣耀将以“____文化”为主题推出限定皮肤,为乡村振兴加油? 王者荣耀6月28日每日一题答案
- 最前线 | 腾讯游戏发布40余款产品与项目,《王者荣耀》发布全新规划
- 腾讯游戏发布40余款产品与项目,《王者荣耀》发布全新规划
- 联发科天玑9000+之王浮出水面,极有可能又是vivo
- 黄渤让四位导师演戏演到崩溃,王一博撒娇,钟汉良一秒入戏
- 联发科天玑9000+之王预定!蓝厂系新旗舰曝光
- OPPO|iPhone14ProMax渲染图:两个王炸让我破防,苹果将再次成功
- 学生党|谁才是千元机之王 学生党千元机推荐
- 摩托罗拉|像素之王来了 摩托罗拉新旗舰影像参数敲定:2亿主摄加持
- 苹果公司|这回轮到中国企业将苹果踢“出局”,放弃虚名,公平合作才是王道
