王小川|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写锁最好 , 拿不到也不能堵塞后边的业务逻辑 , 先放弃 。 再重试执行这个命令 。
四、总结
坚持学习、坚持写作、坚持分享是咔咔从业以来所秉持的信念 。 愿文章在偌大的互联网上能给你带来一点帮助 , 我是咔咔 , 下期见 。
- 自动驾驶|华为首秀自动驾驶,王兴:特斯拉遇到技术与忽悠能力相当的对手了
- 小米12|自研动态性能调度!小姐姐实测小米12 Pro《王者荣耀》:功耗下降20%
- 王中林院士的拓展麦克斯韦方程,这项成果究竟有多大?
- 尴尬了!鸿星尔克与王者荣耀联名宣发翻车,两次发文皆未得到回应
- 新年新气象。|深度 | 创造“世界记录”!江苏这个王牌实验室为何收获多?
- 王中林|华为全球专利榜第四;京东海外开设机器人零售实体店;Oculus遭反垄断调查|科技周报
- 三星|这一招漂亮!英特尔对华“宣战”48小时内,中方果断亮出一张王牌
- 小米科技|小米10S不是最佳选择?三款不到2500元的曲屏手机:最强王者诞生
- ceo|1 库克=0.5薇娅,苹果CEO打不过"带货女王"?
- 祝贺王亚平,成为首位在轨超100天的女航天员!