数据库 mysql 锁详细介绍&数据表锁分析技巧

mysql数据库引擎中的InnoDb下的行锁、表锁、意向锁等

行锁

mysql的行锁是通过索引加载的,即是行锁是加在索引响应的行上的,要是对应的SQL语句没有走索引,则会全表扫描

行锁类型

共享锁 和 排它锁


共享锁(S锁)

也叫读锁。当一个事务对某几行上读锁时,允许其他事务对这几行进行读操作,但不允许其进行写操作,也不允许其他事务给这几行上排它锁,但允许上读锁。

SELECT column FROM table ... LOCK IN SHARE MODE;

排它锁(X锁)

也叫写锁。当一个事务对某几个上写锁时,不允许其他事务写,但允许读。更不允许其他事务给这几行上任何锁。包括写锁。
如果在一条select语句后加上for update,则查询到的数据会被加上一条排它锁,其它事务可以读取,但不能进行更新和插入操作

SELECT column FROM table ... FOR UPDATE;

间隙锁

当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内并不存在的记录,叫做间隙

InnoDB也会对这个"间隙"加锁,这种锁机制就是所谓的间隙锁

表锁

就是没有对没有索引字段上进行事务操作,会导致表锁,其实也可以叫意向锁


意向锁

意向锁产生的主要目的是为了处理行锁和表锁之间的冲突,事务在请求S锁和X锁前,需要先获得对应的IS、IX锁,在为数据行加共享 / 排他锁之前,InooDB 会先获取该数据行所在在数据表的对应意向锁。
如果没有意向锁的话,则需要遍历所有整个表判断是否有行锁的存在,以免发生冲突
如果有了意向锁,只需要判断该意向锁与即将添加的表级锁是否兼容即可。因为意向锁的存在代表了,有行级锁的存在或者即将有行级锁的存在。因而无需遍历整个表,即可获取结果
举例mysql中添加一个排他锁流程是这样的,首先去获取意向排他锁这时会去检测是否有其他已经占用的锁并且是否存在冲突,如果不冲突则获取到意向排他锁,是否存在当前行有排他锁或范围内的间隙锁如果没有则加上排他锁


意向锁类型

意向共享锁 和意向排它锁
意向锁之前是相互兼容的
排他锁持有后其他不管什么锁都是冲突的

数据库 mysql 锁详细介绍&数据表锁分析技巧

查看innodb引擎的运行时信息
show engine innodb status
查看锁表情况
show status like \'Table%\';
查询表级锁争用情况 Table_locks_immediate 指的是能够立即获得表级锁的次数 Table_locks_waited 指的是不能立即获取表级锁而需要等待的次数

获取锁定次数、锁定造成其他线程等待次数,以及锁定等待时间信息

查看造成死锁的sql语句,分析索引情况,然后优化sql语句;

show status like \'%lock%\';
查看超时时间:
show variables like \'%timeout%\';

+—————————-+——–+
| Variable_name | Value |
+—————————-+——–+
| Table_locks_immediate | 795505 |
| Table_locks_waited | 0 |
| Table_open_cache_hits | 0 |
| Table_open_cache_misses | 0 |
| Table_open_cache_overflows | 0 |
+—————————-+——–+
5 rows in set (0.00 sec)

Table_locks_immediate 指的是能够立即获得表级锁的次数
Table_locks_waited 指的是不能立即获取表级锁而需要等待的次数,如果数量大,说明锁等待多,有锁争用情况

查看正在被锁定的的表
show OPEN TABLES where In_use > 0;
mysql> show OPEN TABLES where In_use > 0;
+————–+—————+——–+————-+
| Database | Table | In_use | Name_locked |
+————–+—————+——–+————-+
| music | class_record | 1 | 0 |
| vipswoole | chat_message | 3 | 0 |
| music | user_account | 1 | 0 |
| music | sales_channel | 1 | 0 |
| music | class_room | 5 | 0 |
| music | user | 1 | 0 |
| music_school | user | 1 | 0 |
+————–+—————+——–+————-+
7 rows in set (0.00 sec)

查看正在锁的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
等待锁定
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
如果查看到锁争用情况严重,可以再查看当前执行的SQL :
查看当前线程处理情况,如果不使用full关键字,信息字段中只会显示每个语句的前100个字符。

show processlist;
show full processlist;

SELECT * FROM information_schema.PROCESSLIST;
查询正在执行的进程
SELECT * FROM information_schema.PROCESSLIST where length(info) >0 ;
(mysqladmin -uroot -p -P 3306 processlist)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzwdxd.html