美文网首页
MDL 加锁细说

MDL 加锁细说

作者: baboon | 来源:发表于2016-04-22 16:12 被阅读516次

    几种典型语句的加(释放)锁流程

    1.select语句操作MDL锁流程

      1. Opening tables阶段,加共享锁
      • a) 加MDL_INTENTION_EXCLUSIVE锁
      • b) 加MDL_SHARED_READ锁
      1. 事务提交阶段,释放MDL锁
      • a) 释放MDL_INTENTION_EXCLUSIVE锁
      • b) 释放MDL_SHARED_READ锁

    2. DML语句操作MDL锁流程

      1. Opening tables阶段,加共享锁
      • a) 加MDL_INTENTION_EXCLUSIVE锁
      • b) 加MDL_SHARED_WRITE锁
    • 2)事务提交阶段,释放MDL锁

      • a) 释放MDL_INTENTION_EXCLUSIVE锁
      • b) 释放MDL_SHARED_WRITE锁

    3. alter操作MDL锁流程

      1. Opening tables阶段,加共享锁
      • a) 加MDL_INTENTION_EXCLUSIVE锁
      • b) 加MDL_SHARED_UPGRADABLE锁,升级到MDL_SHARED_NO_WRITE锁
      1. 操作数据,copy data,流程如下:
      • a) 创建临时表tmp,重定义tmp为修改后的表结构
      • b) 从原表读取数据插入到tmp表
      1. 将MDL_SHARED_NO_WRITE读锁升级到MDL_EXCLUSIVE锁
      • a) 删除原表,将tmp重命名为原表名
    • 4)事务提交阶段,释放MDL锁

      • a) 释放MDL_INTENTION_EXCLUSIVE锁
      • b) 释放MDL_EXCLUSIVE锁

    参考

    http://m.blog.itpub.net/22664653/viewspace-1791608/

    1. 事务开始begin transaction的位置

    MySQL的设计:在设置的autocommit=0;read_commited的时候,无论session的第一条语句是select还是dml,都开始一个事务,然后直到commit,所持有的MDL锁也一直维持到commit结束。
      Oracle的设计:在session的第一条更新语句发起时,才创建transaction,在读多的系统上,减少了阻塞的发生可能性。特别是在开发人员发起select语句时,认为没有更新,就不再commit。但在MySQL上,发起select语句,而忘记commit,是非常危险的。

    2. ddl语句阻塞

    MySQL的设计:ddl语句发起时,如果无法获取排他锁,那么ddl将进入阻塞状态,但由于是queue的设计,就阻塞了后续所有的dml和selec操作,在高并发系统上,可能会引起雪崩。
    ** Oracle的设计:**在oracle 11g之前,ddl语句是fast fail的,不进入阻塞状态,所以繁忙的表进行ddl操作时,经常遇到的错误:ORA-00054: resource busy。但在11g之后虽然可以进行阻塞,并提供了ddl_time_out这样的参数进行控制,但在高并发的系统上,运维的操作依然不采用,而是fast fail。

    参考:
    http://www.cnblogs.com/cchust/p/4364220.html

    各种sql语句锁表汇总
    http://www.thinksaas.cn/topics/0/465/465659.html

    相关文章

      网友评论

          本文标题:MDL 加锁细说

          本文链接:https://www.haomeiwen.com/subject/fyrxrttx.html