几种典型语句的加(释放)锁流程
1.select语句操作MDL锁流程
- Opening tables阶段,加共享锁
- a) 加MDL_INTENTION_EXCLUSIVE锁
- b) 加MDL_SHARED_READ锁
- 事务提交阶段,释放MDL锁
- a) 释放MDL_INTENTION_EXCLUSIVE锁
- b) 释放MDL_SHARED_READ锁
2. DML语句操作MDL锁流程
- Opening tables阶段,加共享锁
- a) 加MDL_INTENTION_EXCLUSIVE锁
- b) 加MDL_SHARED_WRITE锁
-
2)事务提交阶段,释放MDL锁
- a) 释放MDL_INTENTION_EXCLUSIVE锁
- b) 释放MDL_SHARED_WRITE锁
3. alter操作MDL锁流程
- Opening tables阶段,加共享锁
- a) 加MDL_INTENTION_EXCLUSIVE锁
- b) 加MDL_SHARED_UPGRADABLE锁,升级到MDL_SHARED_NO_WRITE锁
- 操作数据,copy data,流程如下:
- a) 创建临时表tmp,重定义tmp为修改后的表结构
- b) 从原表读取数据插入到tmp表
- 将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
网友评论