• 事务访问数据时,会 自动给表加MDL读锁、
  • 事务修改元数据时,会自动给表加MDL写锁
  • 遇到锁不兼容时,申请MDL锁的事务形成一个队列

image.png
TxA 获取MDL读锁,TXB 获取MDL写锁,MDL读锁和写锁是不兼容的,所以TxB会阻塞住
TXC 也要加MDL读锁,但是元数据读锁和元数据读锁不是互斥的,事务A加了MDL读锁,事务C也能往上加MDL读锁,但是如果有锁等待,那么后面的事务就自动变成一个队列,事务C挂不上锁,因为前面有个事务B在申请写锁,事务D也挂不上锁。
所以此时队列中
B等待加写锁,C和D等待加读锁。

解决办法

  • alter table之前,查看是否有长事务还未提交
  • 查看长事务:information_schema库innodb_trx表

    如何查看影响性能的锁

  • 查看长事务:information_schema库innodb_trx表

  • 查看锁:information_schema库INNODB_LOCKS表
  • 查看阻塞的事务:

information_schema库INNODB_LOCK_WAITS表

如何查看影响性能的锁(8.0)

  • 查看锁:performance_schema库data_locks表
  • 查看锁等待:performance_schema库data_lock_waits表
  • 查看MDL锁:performance_schema库metadata_locks表

    业务上的建议

  • 控制长事务,没有必要的情况下不开启事务

  • 数据修改(当前读)尽量放在事务候补