mysql的锁
一、锁的分类:
-
锁粒度:
- 表级锁 (mysam)
- 行级锁 (innodb)
-
用途:
- 读锁:共享锁,只读不可写(包括当前事务,当前会话中的其他表不可以更新、) ,多个读互不阻塞
- 写锁:独占锁,排它锁,写锁会阻塞其它事务(不包括当前事务)的读和它锁
-
实现 :
- 存储引擎:自行实现其锁策略和锁粒度
- 服务器级:实现了锁,表级锁,用户可显式
-
请求分类:
- 隐式锁:由存储引擎自动施加锁
- 显式锁:用户手动请求
二、锁的策略
在锁粒度及数据安全性寻求的平衡机制
三、锁的使用示例
3.1 显式使用锁
3.1.1 表锁:
- 加锁
LOCK TABLES tbl_name [[AS] alias] lock_type
[, tbl_name [[AS] alias] lock_type] …
lock_type: READ , WRITE
Database changed
MariaDB [hellodb]> lock table students read;
Query OK, 0 rows affected (0.00 sec)
MariaDB [hellodb]> grant all privileges on hellodb.* to 'a'@'192.168.%' identified by 'a';
ERROR 1100 (HY000): Table 'user' was not locked with LOCK TABLES
注意:此时在被锁住表的会话中,不可以更新其他表;但另外的会话可以
-
解锁 UNLOCK TABLES
MariaDB [hellodb]> unlock tables ; Query OK, 0 rows affected (0.00 sec) MariaDB [hellodb]>
另一种通过kill 进程的方式
show processlist; 查看对应的进程id
kill id 杀死 锁表的进程;
注意:如果不是root 用户看不见所有的进程;千万不要让root锁了进程
MariaDB [hellodb]> show processlist ; +----+------+---------------------+---------+---------+------+------------------------------+-----------------------------------------+----------+ | Id | User | Host | db | Command | Time | State | Info | Progress | +----+------+---------------------+---------+---------+------+------------------------------+-----------------------------------------+----------+ | 35 | root | localhost | hellodb | Query | 0 | init | show processlist | 0.000 | | 39 | a | 192.168.1.102:50178 | hellodb | Query | 14 | Waiting for table level lock | update teachers set age=20 where tid=6 | 0.000 | | 49 | zz | 192.168.1.102:50198 | hellodb | Sleep | 27 | | NULL | 0.000 | +----+------+---------------------+---------+---------+------+------------------------------+-----------------------------------------+----------+ 3 rows in set (0.00 sec) MariaDB [hellodb]> kill 49; Query OK, 0 rows affected (0.00 sec)
3.1.2 全局锁
FLUSH TABLES [tb_name[,…]] [WITH READ LOCK]
关闭正在打开的表(清除查询缓存),通常在备份前加全局读锁
MariaDB [hellodb]> flush tables ;
Query OK, 0 rows affected (0.00 sec)
MariaDB [hellodb]>
3.1.3 查询时加锁
SELECT clause [FOR UPDATE | LOCK IN SHARE MODE]
查询时加写或读锁
3.14 死锁
场景:如图图中的两条黑线分别代表事务1何事务2,在时间点t1都开启了事务,然后分别对A表的K行和B表中的K行进行更改操作,(此时AK行被事务1锁住,BK行被事务2锁住,因为事务1和2都没有提交);之后事务1对B表中的K行更新操作,事务2对A表中的K行更改操作,则此时就会发生死锁,无论哪个事务级别都无法避免;系统会自动杀掉用时短的事务,让另一个事务执行下去
例子:
session 1
mysql> begin ;
Query OK, 0 rows affected (0.00 sec)
mysql> update students set age =7 where stuid=24 ;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> update teachers set age=7 where tid=6; (发生死锁)
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
session 2
MariaDB [hellodb]> begin ;
Query OK, 0 rows affected (0.00 sec)
MariaDB [hellodb]> update teachers set age =11 where tid=6 ;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1 Changed: 0 Warnings: 0
MariaDB [hellodb]> update students set age =11 where stuid=24 ; (卡一会)
Query OK, 0 rows affected (10.91 sec)
Rows matched: 1 Changed: 0 Warnings: 0
3.2 显式使用锁
数据库更改记录时插入自动完成,不用手动完成
=24 ; (卡一会)
Query OK, 0 rows affected (10.91 sec)
Rows matched: 1 Changed: 0 Warnings: 0
#### 3.2 显式使用锁
数据库更改记录时插入自动完成,不用手动完成
来源:CSDN
作者:山贼王
链接:https://blog.csdn.net/qq_36801585/article/details/104101066