InnoDB中锁的查看

时间:2018-06-03 10:25:54   收藏:0   阅读:188

Ⅰ、 show engine innodb status\G

1.1 实力分析一波

锁介绍的那篇中已经提到了这个命令,现在我们开一个参数,更细致的分析一下这个命令

(root@localhost) [(none)]> set global innodb_status_output_locks=1;
Query OK, 0 rows affected (0.00 sec)
(root@localhost) [test]> begin;
Query OK, 0 rows affected (0.00 sec)

(root@localhost) [test]> delete from l where a = 2;
Query OK, 1 row affected (0.00 sec)

(root@localhost) [test]> update l set b = b + 1 where a = 4;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

(root@localhost) [test]> show engine innodb status\G
...
------------
TRANSACTIONS
------------
Trx id counter 30217417
Purge done for trx‘s n:o < 30217417 undo n:o < 0 state: running but idle
History list length 74
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 30217412, ACTIVE 37 sec
2 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 2
MySQL thread id 355, OS thread handle 140483080300288, query id 1263 localhost root starting
show engine innodb status
TABLE LOCK table `test`.`l` trx id 30217412 lock mode IX
RECORD LOCKS space id 1358 page no 3 n bits 72 index PRIMARY of table `test`.`l` trx id 30217412 lock_mode X locks rec but not gap
Record lock, heap no 2 PHYSICAL RECORD: n_fields 6; compact format; info bits 32
 0: len 4; hex 80000002; asc     ;;
 1: len 6; hex 000001cd14c4; asc       ;;
 2: len 7; hex 2400000fc21499; asc $      ;;
 3: len 4; hex 80000004; asc     ;;
 4: len 4; hex 80000006; asc     ;;
 5: len 4; hex 80000008; asc     ;;

Record lock, heap no 3 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
 0: len 4; hex 80000004; asc     ;;
 1: len 6; hex 000001cd14c4; asc       ;;
 2: len 7; hex 2400000fc214c8; asc $      ;;
 3: len 4; hex 80000007; asc     ;;
 4: len 4; hex 80000008; asc     ;;
 5: len 4; hex 8000000a; asc     ;;
...

解析:

Q? 表中是四个列,为什么这把是6个列?

1.2、趁热打铁,分析一下等待的情况

session1:

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

(root@localhost) [test]> delete from l where a = 2;
Query OK, 1 row affected (0.00 sec)

session2:

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

(root@localhost) [test]> select * from l where a=2 for update;
hang住了

session3:

...
------------
TRANSACTIONS
------------
Trx id counter 30217456
Purge done for trx‘s n:o < 30217442 undo n:o < 0 state: running but idle
History list length 4
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 421958478909040, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 30217455, ACTIVE 1741 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 1136, 2 row lock(s)
MySQL thread id 396, OS thread handle 140483215816448, query id 2340 localhost root statistics
select * from l where a=2 for update
------- TRX HAS BEEN WAITING 27 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 1358 page no 3 n bits 72 index PRIMARY of table `test`.`l` trx id 30217455 lock_mode X locks rec but not gap waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 6; compact format; info bits 32
 0: len 4; hex 80000002; asc     ;;
 1: len 6; hex 000001cd14ee; asc       ;;
 2: len 7; hex 230000013d27d5; asc #   =‘ ;;
 3: len 4; hex 80000004; asc     ;;
 4: len 4; hex 80000006; asc     ;;
 5: len 4; hex 80000008; asc     ;;

------------------
TABLE LOCK table `test`.`l` trx id 30217455 lock mode IX
RECORD LOCKS space id 1358 page no 3 n bits 72 index PRIMARY of table `test`.`l` trx id 30217455 lock_mode X locks rec but not gap waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 6; compact format; info bits 32
 0: len 4; hex 80000002; asc     ;;
 1: len 6; hex 000001cd14ee; asc       ;;
 2: len 7; hex 230000013d27d5; asc #   =‘ ;;
 3: len 4; hex 80000004; asc     ;;
 4: len 4; hex 80000006; asc     ;;
 5: len 4; hex 80000008; asc     ;;

---TRANSACTION 30217454, ACTIVE 1821 sec
2 lock struct(s), heap size 1136, 1 row lock(s), undo log entries 1
MySQL thread id 355, OS thread handle 140483080300288, query id 2339 localhost root
TABLE LOCK table `test`.`l` trx id 30217454 lock mode IX
RECORD LOCKS space id 1358 page no 3 n bits 72 index PRIMARY of table `test`.`l` trx id 30217454 lock_mode X locks rec but not gap
Record lock, heap no 2 PHYSICAL RECORD: n_fields 6; compact format; info bits 32
 0: len 4; hex 80000002; asc     ;;
 1: len 6; hex 000001cd14ee; asc       ;;
 2: len 7; hex 230000013d27d5; asc #   =‘ ;;
 3: len 4; hex 80000004; asc     ;;
 4: len 4; hex 80000006; asc     ;;
 5: len 4; hex 80000008; asc     ;;
...

Ⅱ、简单点,上面是不是太专业了

2.1 利用三张表写一个sql脚本

重复之前的步骤,一边开一个事务删除2这条记录不提交,另一边用for update查2这条记录
(root@localhost) [(none)]> SELECT
    ->     r.trx_id waiting_trx_id,
    ->     r.trx_mysql_thread_id waiting_thread,
    ->     r.trx_query wating_query,
    ->     b.trx_id blocking_trx_id,
    ->     b.trx_mysql_thread_id blocking_thread,
    ->     b.trx_query blocking_query
    -> FROM
    ->     information_schema.innodb_lock_waits w
    ->         INNER JOIN
    ->     information_schema.innodb_trx b ON b.trx_id = w.blocking_trx_id
    ->         INNER JOIN
    ->     information_schema.innodb_trx r ON r.trx_id = w.requesting_trx_id;
+----------------+----------------+--------------------------------------+-----------------+-----------------+----------------+
| waiting_trx_id | waiting_thread | wating_query                         | blocking_trx_id | blocking_thread | blocking_query |
+----------------+----------------+--------------------------------------+-----------------+-----------------+----------------+
| 30217455       |            396 | select * from l where a=2 for update | 30217454        |             355 | NULL           |
+----------------+----------------+--------------------------------------+-----------------+-----------------+----------------+
1 row in set, 1 warning (0.02 sec)

2.2 走sys库看一把,更简单

5.7才有sys库,不过5.6也可以自行把sys库弄进去

(root@localhost) [(none)]> select * from sys.innodb_lock_waits\G
*************************** 1. row ***************************
                wait_started: 2018-06-03 00:52:01
                    wait_age: 00:00:14
               wait_age_secs: 14
                locked_table: `test`.`l`
                locked_index: PRIMARY
                 locked_type: RECORD
              waiting_trx_id: 30217455
         waiting_trx_started: 2018-06-03 00:11:13
             waiting_trx_age: 00:41:02
     waiting_trx_rows_locked: 5
   waiting_trx_rows_modified: 0
                 waiting_pid: 396
               waiting_query: select * from l where a=2 for update
             waiting_lock_id: 30217455:1358:3:2
           waiting_lock_mode: X
             blocking_trx_id: 30217454
                blocking_pid: 355
              blocking_query: NULL
            blocking_lock_id: 30217454:1358:3:2
          blocking_lock_mode: X
        blocking_trx_started: 2018-06-03 00:09:53
            blocking_trx_age: 00:42:22
    blocking_trx_rows_locked: 1
  blocking_trx_rows_modified: 1
     sql_kill_blocking_query: KILL QUERY 355
sql_kill_blocking_connection: KILL 355
1 row in set, 3 warnings (0.09 sec)

tips:

Ⅲ、锁超时

刚才模拟锁等待过程中出现了下面得报错

(root@localhost) [test]> select * from l where a=2 for update;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

这叫锁等待超时,开发人员通常把这个和死锁混为一谈

lock持有的时间是以事务为单位的,事务提交后才会把事务里所有的锁释放,这是无法避免的,不过可以通过一个参数来控制超时时间

(root@localhost) [test]> show variables like ‘innodb_lock_wait_timeout‘;
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| innodb_lock_wait_timeout | 50    |
+--------------------------+-------+
1 row in set (0.00 sec)

默认50s,建议设置为3s左右即可

原文:https://www.cnblogs.com/---wunian/p/9122134.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!