mysql的锁

扶醉桌前 提交于 2020-01-28 19:16:22

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 死锁

mark

场景:如图图中的两条黑线分别代表事务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 显式使用锁

数据库更改记录时插入自动完成,不用手动完成

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!