mysql 表级锁

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wll_1017/article/details/86063094


(1) 表锁
表锁的语法是 lock tables … read/write  可以用 unlock tables 主动释放锁 ,可以是客户端断开时候自动释放。需要注意的是,lock tables 语法除了会限制别的线程读写外,也下定了本线程接下来的操作
lock tables t1 read, t2 write  这个语句则其他线程写t1表,读t2表都会被阻塞。同时A在执行unlock tables 之前,也只能执行读t1,读写t2

(2)元数据锁
MDL锁是为了在访问表数据的时候,表结构不会被变更
当对一个表做增删改查操作的时候,加MDL读锁;当对表做结构变更操作的时候,加MDL写锁
  读锁之间不互斥,因此可以有多个线程同时对一个表增删改查
  读写锁之间,写锁之间是互斥的,用来保证表结构操作更安全


session1:
(root@33306) [test]> begin;
Query OK, 0 rows affected (0.00 sec)

(root@33306) [test]> select *from t2 limit 1;
+------+--------+
| c1   | c2     |
+------+--------+
| NULL | mothra |
+------+--------+
1 row in set (0.00 sec)


session2:
(root@33306) [test]> select *from t2 limit 1;
+------+--------+
| c1   | c2     |
+------+--------+
| NULL | mothra |
+------+--------+
1 row in set (0.00 sec)

(root@33306) [test]> alter  table t2 add id int;
hang 住

原因是: session1 对表t2加了MDL读锁,session2 对表T2要加MDL写锁,两个锁互斥,所以session2 hang住


查看哪些表被锁了
(root@33306) [test]> show open tables where in_use>0;
+----------+-------+--------+-------------+
| Database | Table | In_use | Name_locked |
+----------+-------+--------+-------------+
| test     | t2    |      1 |           0 |
+----------+-------+--------+-------------+
1 row in set (0.00 sec)


(root@33306) [(none)]> SELECT
    -> a.trx_id,
    -> b.ID,
    -> b.STATE,
    -> b.COMMAND,
    -> b.`USER`,
    -> b.`HOST`,
    -> b.DB,
    -> a.trx_weight,
    -> a.trx_query,
    -> a.trx_tables_locked,
    -> a.trx_state,
    -> a.trx_started,
    -> a.trx_requested_lock_id,
    -> a.trx_wait_started,
    -> a.trx_mysql_thread_id
    -> FROM  information_schema.INNODB_TRX a ,information_schema.PROCESSLIST b  where a.trx_mysql_thread_id=ID
    -> 
    -> ;
+-----------------+-------+-------+---------+------+-----------------+------+------------+-----------+-------------------+-----------+---------------------+-----------------------+------------------+---------------------+
| trx_id          | ID    | STATE | COMMAND | USER | HOST            | DB   | trx_weight | trx_query | trx_tables_locked | trx_state | trx_started         | trx_requested_lock_id | trx_wait_started | trx_mysql_thread_id |
+-----------------+-------+-------+---------+------+-----------------+------+------------+-----------+-------------------+-----------+---------------------+-----------------------+------------------+---------------------+
| 421614036035408 | 27123 |       | Sleep   | root | localhost:56969 | test |          0 | NULL      |                 0 | RUNNING   | 2019-01-08 09:54:50 | NULL                  | NULL             |               27123 |
+-----------------+-------+-------+---------+------+-----------------+------+------------+-----------+-------------------+-----------+---------------------+-----------------------+------------------+---------------------+
1 row in set (0.00 sec)


可以发现是27123 这个session1 发起的,通过show processlist 查看,可以发现27071 在Waiting for table metadata lock 
(root@33306) [(none)]> show processlist;
+-------+-----------------+--------------------+------+---------+---------+---------------------------------+-----------------------------+
| Id    | User            | Host               | db   | Command | Time    | State                           | Info                        |
+-------+-----------------+--------------------+------+---------+---------+---------------------------------+-----------------------------+
|     1 | event_scheduler | localhost          | NULL | Daemon  | 1107864 | Waiting on empty queue          | NULL                        |
| 27071 | root            | localhost:55892    | test | Query   |     132 | Waiting for table metadata lock | alter  table t2 add id3 int |
| 27087 | root            | 192.168.9.44:62103 | NULL | Sleep   |      17 |                                 | NULL                        |
| 27123 | root            | localhost:56969    | test | Sleep   |      27 |                                 | NULL                        |
| 27125 | monitor         | anedbtest01:36359  | NULL | Sleep   |       1 |                                 | NULL                        |
| 27127 | monitor         | anedbtest01:36417  | NULL | Sleep   |      31 |                                 | NULL                        |
| 27129 | root            | localhost:57073    | NULL | Query   |       0 | starting                        | show processlist            |
+-------+-----------------+--------------------+------+---------+---------+---------------------------------+-----------------------------+
7 rows in set (0.00 sec)

从上面可以看到27123 线程加了的MDL锁,阻塞了27071线程的MDL锁,根据业务是否可以杀掉27123线程

猜你喜欢

转载自blog.csdn.net/wll_1017/article/details/86063094