数据库5.5之后的metadata lock之坑

mysql在从5.1升级到5.5之后,为了解决ddl与dml两种语法可能造成的冲突问题,引入了metadata lock,至于这两者的区别是什么,我的理解是前者是用来修改、操作表结构的语句,后者是用来修改维护表数据的语法:

参考链接

参考链接2

参考链接3

参考链接4

参考链接5

为了防止比如说session1在insert修改表时这个时候session2进行了alter操作所以在5.5之后引入metadata lock,这样在session1运行的时候其他的回话也可以进行insert、select操作,但是一旦进行alter、drop操作,则会被session1的metadata lock阻塞住,这个时候如果session2在等待mdl的话,其他的session再想进行select的时候又会等待2释放mdl这样的后果就是造成了所有连接的阻塞等待

这种情况多发生在,session1开始了一个事务操作【begin】如果在运行完后不进行commit操作并且不断开连接的情况下那么极有可能阻塞,在5.1之前是没有这个问题的,这个机制不限数据库引擎的,myisam也会受到事务的影响,测试方法如下采用myisam引擎:

1,session1 交互界面中begin

2,select * from tablename limit 1

3,session2 alter table tablename。。。这个时候session2就会被阻塞住,一直到session执行了commit操作

当时在排查这个问题的时候,由于代码里面并没有主动执行begin操作,所以很纳闷为什么同样会发生这种锁表的情况呢,后来经过查找资料发现原因是,python的mysqldb中创建一个cursor就相当于默认开启了一个事务,参考链接其中有一段话是’For databases that support transactions, the Python interface silently starts a transaction when the cursor is created. The commit() method commits the updates made using that cursor, and the rollback() method discards them.’,测试方法,就是使用MySQLdb进行连接数据库自后select操作table之后,不关闭连接,这个时候尝试altertable的操作就会进行阻塞,相反,如果在select之后进行commit操作,这个时候是不会产生mdl的。

转载请注明来源链接 http://just4fun.im/2016/09/29/e6-95-b0-e6-8d-ae-e5-ba-935-5-e4-b9-8b-e5-90-8e-e7-9a-84metadata-lock-e4-b9-8b-e5-9d-91/ 尊重知识,谢谢:)