MySQL的锁包括服务器级别的锁,存储引擎级别的锁,及互斥锁。服务器级别的锁包括表锁和元数据锁,存储引擎的锁是行级别的锁,由InnoDB引擎控制。互斥锁是低级别的锁,适用于内部的资源,用于同步低级别代码的操作,确保一次只有一个线程能够访问,例如,日志文件、自增列的计数器,及InnoDB buffer pool的互斥。
如何识别锁争用?
用户首先需要了解InnoDB的锁,之后可以通过如下方法识别不同的锁争用:
InnoDB表锁
InnoDB的表锁包括共享锁S、排他锁X、意向共享锁IS,及意向排他锁。
共享锁S:对表加锁用于读取
排它锁X:对表加锁用于写入
意向共享锁IS:对表加锁,以允许执行行级别的共享锁
意向排它锁IX:对表加锁,以允许执行行级别的排它锁
当一个事务对表加锁时,如果遇到另一个事务的锁,需要两个事务的锁类型兼容才能够获得锁。表锁类型的兼容矩阵如下:
X | IX | S | IS | |
---|---|---|---|---|
X | 冲突 | 冲突 | 冲突 | 冲突 |
IX | 冲突 | 兼容 | 冲突 | 兼容 |
S | 冲突 | 冲突 | 兼容 | 兼容 |
IS | 冲突 | 兼容 | 兼容 | 兼容 |
InnoDB的行锁
一个事务在获得行锁之前必须获得表的意向锁(IS或IX)
假设,事务A对一行具有排他锁,事务B请求对该行加共享锁,由于两个类型的锁冲突,事务B被阻塞执行,等待获得行锁。假设,事务C对一行具有共享锁,事务D同样对该行加共享锁,两个事务的锁不发生冲突,则事务D可以获得锁。
MySQL提供了非锁定读取功能。一个正常的SELECT语句不使用“FOR SHARE”或“FOR UPDATE”时,读取InnoDB的数据不需要获取任何锁,如果使用“FOR SHARE”则要求一个共享锁,使用“FOR UPDATE”将要求一个排他锁。
使用SHOW PROCESSLIST获取锁信息
使用“SHOW PROCESSLIST”在输出的“state”列中显示锁的相关信息:
“State: Waiting for table metadata lock”表示表具有冲突的锁
“State: update”或“State: Searching rows for update ”表示具有InnoDB锁(表锁或行锁)
注意,使用“SHOW PROCESSLIST”无法获得锁的内部信息,用户也可以查询Performance Schema中的threads表获得同样的信息。推荐用户使用Performance Schema,可以减少对服务器性能的影响。
使用Performance Schema和Information Schema监视锁
Performance Schema和Information Schema中的视图包含与事务关联的锁信息,包括正在加锁和被锁的语句:
以上内容是关于如何识别MySQL的锁,及监视MySQL锁的简介。感谢您关注“MySQL解决方案工程师”!
本文分享自 MySQL解决方案工程师 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!