了解一下Mysql的MDL锁

产生的原因

事务访问数据时会自动加MDL锁,也就是元数据读锁。这个事务访问数据不是当前读,不是forupdate,只是普通的select。
事务修改元数据的时候,会自动给表加MLD写锁。也就是加写锁,别的表都不能访问该表数据了。
在项目大规模上线改表的时候,有时候会给网站下线,上线成功后才会打开。
举例:下面四个事务A、B、C、D,A只是简单的快照读,不加任何行锁和表锁,但是会加MDL读锁,加锁后会禁止一切事务修改表数据的,等事务提交后才能动表数据。这时候 事务B修改表了,这时候要获取MDL写锁,因为MDL写锁和MDL读锁是互斥的,所以要获取MDL写锁的B会阻塞等待;这时候事务C查表,按理说应该是MDL读锁,在此之前事务A也是MDL读锁,事务C也能往上加MDL读锁,但是MDL锁假如有锁等待,两种锁不兼容那么会自动成一个队列,但是在事务C之前有一个事务B,所以加不上,及时和事务A的MDL锁是兼容的也加不上,事务D也等着加MDL读锁,就是因为事务B不兼容,所以加不上。

 

 解决办法

查看长事务
alter table之前查看是否有长事务还未提交,首先不要在业务高峰期做,如果前面有长事务没提交,那么你这时候要获取MDL写锁,那么这时候后面所有读的都被阻塞了,如果不加写锁,后面的读会兼容的。

查看长事务:information_schema库innodb_trx表,有事务号、事务开启时间等,观察事务的长短。

如何查看影响性能的锁
查看所有锁:information_schema库的INNODB_LOCKS表,有关行锁和其他锁的问题,锁的记录,看哪些锁时间长,哪些锁有问题。
查看阻塞的事务:information_schema库INNODB_LOCK_WAITS表,影响性能的阻塞问题

mysql 8.0新增
performance_schema库data_locks表
performance_schema库data_lock_waits表,有关阻塞的问题
查看MDL锁:performance_schema库metadata_locks表,在alter表的之前先看看这个表

业务上尽量不开启事务,也尽量不要长事务

数据修改(当前读)时候尽量放在事务后,降低锁时间

原文地址:https://www.cnblogs.com/wt645631686/p/9744838.html