了解一下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表的之前先看看这个表
业务上尽量不开启事务,也尽量不要长事务
数据修改(当前读)时候尽量放在事务后,降低锁时间
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
2014-10-05 使整个页面变灰的css代码