MySQL锁导致的查询慢分析

时间:2022-10-20 18:00:26

全局锁

全局锁的典型使用场景是,做全库逻辑备份。一致性视图也可以备份,但是只有支持事务的引擎可以。

所以需要FTWRL备份 因为如果不加锁的话,备份系统备份的得到的库不是一个逻辑时间点,这个视图是逻辑不一致的。 当 mysqldump 使用参数–single-transaction 的时候, 导数据之前就会启动一个事务,来确保拿到一致性视图。而由于 MVCC 的支持, 这个过程中数据是可以正常更新的。 为什么还需要 FTWRL 呢?一致性读是好,但前提是引擎要支持这个隔离级别。 比如,对于 MyISAM 这种不支持事务的引擎,如果备份过程中有更新, 总是只能取到最新的数据,那么就破坏了备份的一致性。 这时,我们就需要使用 FTWRL 命令了。


表级锁

表级别的锁有两种:

一种是表锁,一种是元数据锁(meta data lock,MDL)。

表级别的写锁,本线程可以读写。


MDL锁

在 MySQL 5.5 版本中引入了 MDL,当对一个表做增删改查操作的时候,加 MDL 读锁; 当要对表做结构变更操作的时候,加 MDL 写锁。

1、读锁之间不互斥,因此你可以有多个线程同时对一张表增删改查。

2、读写锁之间、写锁之间是互斥的,用来保证变更表结构操作的安全性。 因此,如果有两个线程要同时给一个表加字段,其中一个要等另一个执行完才能开始执行。

3、MDL 会直到事务提交才释放。


行锁

两阶段协议 在 InnoDB 事务中,行锁是在需要的时候才加上的,但并不是不需要了就立刻释放, 而是要等到事务结束时才释放。这个就是两阶段锁协议。


查询慢分析

等 MDL 锁

show processlist 命令查看 Waiting for table metadata lock 可通过查询 sys.schema_table_lock_waits 找出造成阻塞的 process id, kill 命令断开即可。


等 flush

出现 Waiting for table flush 状态的可能情况是: 有一个 flush tables 命令被别的语句堵住了,然后它又堵住了我们的 select 语。


等行锁查询

select * from sys.innodb_lock_waits where locked_table='`test`.`t`'\G