zoukankan      html  css  js  c++  java
  • InnoDB意向锁和插入意向锁

     
    Preface
     
        Last night one buddy in tech wechat group asked "what's intention locks of InnoDB?"Thus,I'm gonna say someting about it.As we all know,there're various types of lock in InnoDB engine such as record locks,gap locks,next key locks and so forth.Intention locks is another kind of granularity of lock of InnoDB.
     
    Introduce
     
    1. Intention Locks
     
        Intention locks of InnoDB are table-level locks.It's generated to indicate which type of lock relevant to a certain row in which the transaction will involve(shared or exclusive lock).It seems like that one guy is booking a ticket of the train to somewhere while the ticket system broadcasts there's a guy mean to ocuppy a seat of certain compartment in the train.But it does not block the action of booking ticket on the same train from another guy at the same time(another intention lock).That is,intention locks does not block each other at all only if you are modify the same row(booking the same seat).It's the effect of exclusive lock instead of intention lock.
     
        There're two kinds of intention locks in InnoDB:
    • Intention shared lock(IS): It indicates that a transaction is setting(or going to set) a shared lock on several rows for shared query operations.
    • Intention exclusive lock(IX): It indicates that a transaction is setting(or going to set) a exclusive lock on several rows for exclusive modification operations.
     
        Notice,any transaction who want to get row-level lock(shared or exclusive lock) on a record in a table must get the intention locks first.Generally speaking,S row-level lock is versus IS while X row-level lock is versus IX.There conflict relationship shows below.
     
     XIXSIS
    X Conflict Conflict Conflict Conflict
    IX Conflict Compatible Conflict Compatible
    S Conflict Conflict Compatible Compatible
    IS Conflict Compatible Compatible Compatible

       What we can see is that intention locks does not conflict themselves and always be compatible.In most scenarios,Intention locks do not block other transactions except for operation like "lock table ... writ;".The purpose of intention locks is to tell Innodb that someone is gonna add a lock on those relevant rows(for later reading or modifying) in a target table.
     
    2. Insert Intention Locks
     
        Now we've known clearly about intention locks,but what's the insert intention locks?Are the intention locks relevant with insert operations?Almost,it actually related to gap lock generated by insert operation.It indicates that transactions of insert do not need to wait for each other if they are not inserting at same position within the gap when they later get the exclusive locks on those inserted rows .
     
    Examples
     
    1. Intention locks test in the same session with "innodb_status_output_locks=off".
     1 zlm@192.168.56.100:3306 [zlm]>select @@transaction_isolation;
     2 +-------------------------+
     3 | @@transaction_isolation |
     4 +-------------------------+
     5 | REPEATABLE-READ         |
     6 +-------------------------+
     7 1 row in set (0.00 sec)
     8 
     9 zlm@192.168.56.100:3306 [zlm]>show variables like '%status%';
    10 +----------------------------+-------+
    11 | Variable_name              | Value |
    12 +----------------------------+-------+
    13 | innodb_status_output       | ON    | //If set "on",it prints innodb status into error log and refresh every 20s by default.
    14 | innodb_status_output_locks | OFF   | //If set "off",there're no intention locks in result of "show engine innodb status;".
    15 +----------------------------+-------+
    16 2 rows in set (0.01 sec)
    17 
    18 zlm@192.168.56.100:3306 [(none)]>select @@autocommit;
    19 +--------------+
    20 | @@autocommit |
    21 +--------------+
    22 |            1 | //If does not specify "begin" or "start transaction" to explicitly generate a transaction,it commits after typing enter.
    23 +--------------+
    24 1 row in set (0.00 sec)
    25 
    26 zlm@192.168.56.100:3306 [zlm]>show create table tG
    27 *************************** 1. row ***************************
    28        Table: t
    29 Create Table: CREATE TABLE `t` (
    30   `id` int(11) NOT NULL,
    31   `name` char(10) DEFAULT NULL,
    32   KEY `id` (`id`)
    33 ) ENGINE=InnoDB DEFAULT CHARSET=utf8
    34 1 row in set (0.01 sec)
    35 
    36 zlm@192.168.56.100:3306 [zlm]>begin;select * from t where name = 'aaa' lock in share mode;
    37 Query OK, 0 rows affected (0.00 sec)
    38 
    39 +----+------+
    40 | id | name |
    41 +----+------+
    42 |  1 | aaa  |
    43 +----+------+
    44 1 row in set (0.00 sec)
    45 
    46 zlm@192.168.56.100:3306 [zlm]>select * from t for update;
    47 +----+------+
    48 | id | name |
    49 +----+------+
    50 |  1 | aaa  |
    51 |  2 | bbb  |
    52 |  4 | ccc  |
    53 |  6 | fff  |
    54 +----+------+
    55 4 rows in set (0.00 sec)
    56 
    57 [root@zlm1 03:41:54 /data/mysql/mysql3306/data]
    58 #echo '' > error.log 
    59 
    60 [root@zlm1 03:42:04 /data/mysql/mysql3306/data]
    61 #tail -f error.log 
    62 
    63 
    64 ...
    65 ------------
    66 TRANSACTIONS
    67 ------------
    68 Trx id counter 2996009
    69 Purge done for trx's n:o < 2996003 undo n:o < 0 state: running but idle
    70 History list length 12
    71 LIST OF TRANSACTIONS FOR EACH SESSION:
    72 ---TRANSACTION 2996008, ACTIVE 83 sec
    73 4 lock struct(s), heap size 1136, 10 row lock(s)
    74 MySQL thread id 210, OS thread handle 140311521974016, query id 8335 zlm1 192.168.56.100 zlm
    75 ...
    76 
    77 ----------------------------
    78 END OF INNODB MONITOR OUTPUT
    79 ============================
    80 ^C
    81 
    82 //There're no intention locks at all.
    2. Intention locks test in the same session with "innodb_status_output_locks=on".
      1 zlm@192.168.56.100:3306 [zlm]>set @@global.innodb_status_output_locks=on;
      2 Query OK, 0 rows affected (0.00 sec)
      3 
      4 zlm@192.168.56.100:3306 [zlm]>exit
      5 Bye
      6 
      7 [root@zlm1 03:44:23 /data/mysql/mysql3306/data]
      8 #mysql
      9 Welcome to the MySQL monitor.  Commands end with ; or g.
     10 Your MySQL connection id is 217
     11 Server version: 5.7.21-log MySQL Community Server (GPL)
     12 
     13 Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
     14 
     15 Oracle is a registered trademark of Oracle Corporation and/or its
     16 affiliates. Other names may be trademarks of their respective
     17 owners.
     18 
     19 Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.
     20 
     21 zlm@192.168.56.100:3306 [(none)]>select @@transaction_isolation;
     22 +-------------------------+
     23 | @@transaction_isolation |
     24 +-------------------------+
     25 | REPEATABLE-READ         |
     26 +-------------------------+
     27 1 row in set (0.00 sec)
     28 
     29 zlm@192.168.56.100:3306 [(none)]>select @@global.innodb_status_output_locks;
     30 +-------------------------------------+
     31 | @@global.innodb_status_output_locks |
     32 +-------------------------------------+
     33 |                                   1 |
     34 +-------------------------------------+
     35 1 row in set (0.00 sec)
     36 
     37 zlm@192.168.56.100:3306 [(none)]>select @@global.innodb_status_output;
     38 +-------------------------------+
     39 | @@global.innodb_status_output |
     40 +-------------------------------+
     41 |                             1 |
     42 +-------------------------------+
     43 1 row in set (0.00 sec)
     44 
     45 zlm@192.168.56.100:3306 [(none)]>select @@autocommit;
     46 +--------------+
     47 | @@autocommit |
     48 +--------------+
     49 |            1 |
     50 +--------------+
     51 1 row in set (0.00 sec)
     52 
     53 zlm@192.168.56.100:3306 [(none)]>use zlm
     54 Reading table information for completion of table and column names
     55 You can turn off this feature to get a quicker startup with -A
     56 
     57 Database changed
     58 zlm@192.168.56.100:3306 [zlm]>begin;select * from t where name = 'aaa' lock in share mode;
     59 Query OK, 0 rows affected (0.00 sec)
     60 
     61 +----+------+
     62 | id | name |
     63 +----+------+
     64 |  1 | aaa  |
     65 +----+------+
     66 1 row in set (0.00 sec)
     67 
     68 zlm@192.168.56.100:3306 [zlm]>select * from t for update;
     69 +----+------+
     70 | id | name |
     71 +----+------+
     72 |  1 | aaa  |
     73 |  2 | bbb  |
     74 |  4 | ccc  |
     75 |  6 | fff  |
     76 +----+------+
     77 4 rows in set (0.00 sec)
     78 
     79 [root@zlm1 03:42:09 /data/mysql/mysql3306/data]
     80 #tail -f error.log 
     81 
     82 ...
     83 ------------
     84 TRANSACTIONS
     85 ------------
     86 Trx id counter 2996010
     87 Purge done for trx's n:o < 2996003 undo n:o < 0 state: running but idle
     88 History list length 12
     89 LIST OF TRANSACTIONS FOR EACH SESSION:
     90 ---TRANSACTION 2996009, ACTIVE 29 sec
     91 4 lock struct(s), heap size 1136, 10 row lock(s)
     92 MySQL thread id 217, OS thread handle 140311415838464, query id 8738 zlm1 192.168.56.100 zlm
     93 TABLE LOCK table `zlm`.`t` trx id 2996009 lock mode IS //Here's an "IS" intention lock generated by "select ... lock in share mode;" operation.
     94 RECORD LOCKS space id 175 page no 3 n bits 72 index GEN_CLUST_INDEX of table `zlm`.`t` trx id 2996009 lock mode S //Here's a "S" shared lock of records.
     95 Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
     96  0: len 8; hex 73757072656d756d; asc supremum;;
     97 
     98 Record lock, heap no 2 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
     99  0: len 6; hex 000000000700; asc       ;;
    100  1: len 6; hex 0000002db708; asc    -  ;;
    101  2: len 7; hex a8000002610110; asc     a  ;;
    102  3: len 4; hex 80000001; asc     ;;
    103  4: len 10; hex 61616120202020202020; asc aaa       ;;
    104 
    105 Record lock, heap no 3 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
    106  0: len 6; hex 000000000701; asc       ;;
    107  1: len 6; hex 0000002db708; asc    -  ;;
    108  2: len 7; hex a800000261011f; asc     a  ;;
    109  3: len 4; hex 80000002; asc     ;;
    110  4: len 10; hex 62626220202020202020; asc bbb       ;;
    111 
    112 Record lock, heap no 4 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
    113  0: len 6; hex 000000000702; asc       ;;
    114  1: len 6; hex 0000002db708; asc    -  ;;
    115  2: len 7; hex a800000261012e; asc     a .;;
    116  3: len 4; hex 80000004; asc     ;;
    117  4: len 10; hex 63636320202020202020; asc ccc       ;;
    118 
    119 Record lock, heap no 5 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
    120  0: len 6; hex 000000000703; asc       ;;
    121  1: len 6; hex 0000002db721; asc    - !;;
    122  2: len 7; hex 360000012c2a35; asc 6   ,*5;;
    123  3: len 4; hex 80000006; asc     ;;
    124  4: len 10; hex 66666620202020202020; asc fff       ;;
    125 
    126 TABLE LOCK table `zlm`.`t` trx id 2996009 lock mode IX //Here's an "IX" intertion lock generated by "select ... for update;" operation.
    127 RECORD LOCKS space id 175 page no 3 n bits 72 index GEN_CLUST_INDEX of table `zlm`.`t` trx id 2996009 lock_mode X //Here's a "X" exclusive lock of records.
    128 Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
    129  0: len 8; hex 73757072656d756d; asc supremum;;
    130 
    131 Record lock, heap no 2 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
    132  0: len 6; hex 000000000700; asc       ;;
    133  1: len 6; hex 0000002db708; asc    -  ;;
    134  2: len 7; hex a8000002610110; asc     a  ;;
    135  3: len 4; hex 80000001; asc     ;;
    136  4: len 10; hex 61616120202020202020; asc aaa       ;;
    137 
    138 Record lock, heap no 3 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
    139  0: len 6; hex 000000000701; asc       ;;
    140  1: len 6; hex 0000002db708; asc    -  ;;
    141  2: len 7; hex a800000261011f; asc     a  ;;
    142  3: len 4; hex 80000002; asc     ;;
    143  4: len 10; hex 62626220202020202020; asc bbb       ;;
    144 
    145 Record lock, heap no 4 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
    146  0: len 6; hex 000000000702; asc       ;;
    147  1: len 6; hex 0000002db708; asc    -  ;;
    148  2: len 7; hex a800000261012e; asc     a .;;
    149  3: len 4; hex 80000004; asc     ;;
    150  4: len 10; hex 63636320202020202020; asc ccc       ;;
    151 
    152 Record lock, heap no 5 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
    153  0: len 6; hex 000000000703; asc       ;;
    154  1: len 6; hex 0000002db721; asc    - !;;
    155  2: len 7; hex 360000012c2a35; asc 6   ,*5;;
    156  3: len 4; hex 80000006; asc     ;;
    157  4: len 10; hex 66666620202020202020; asc fff       ;;
    158 ...
    159 
    160 ----------------------------
    161 END OF INNODB MONITOR OUTPUT
    162 ============================
    163 ^C
    164 
    165 //We've got an "IS" intention loc,an "IX" intention lock,four "S" locks and four "X" locks.
    166 //Why does "slect ... where name = 'aaa' lock in share mode;" operation holds four "S" locks while we just specify one line?'cause "name" column does not has index key on it.
    167 //Therefore,if we need to observe the intention locks.The variable of "innodb_status_output_locks" should be set "on".
    3. Intention locks test between two sessions.
      1 //Session 1:
      2 zlm@192.168.56.100:3306 [zlm]>select @@global.innodb_status_output;
      3 +-------------------------------+
      4 | @@global.innodb_status_output |
      5 +-------------------------------+
      6 |                             1 |
      7 +-------------------------------+
      8 1 row in set (0.00 sec)
      9 
     10 zlm@192.168.56.100:3306 [zlm]>select @@autocommit;
     11 +--------------+
     12 | @@autocommit |
     13 +--------------+
     14 |            1 |
     15 +--------------+
     16 1 row in set (0.00 sec)
     17 
     18 zlm@192.168.56.100:3306 [zlm]>begin;select * from t where name = 'aaa' lock in share mode;
     19 Query OK, 0 rows affected (0.00 sec)
     20 
     21 +----+------+
     22 | id | name |
     23 +----+------+
     24 |  1 | aaa  |
     25 +----+------+
     26 1 row in set (0.00 sec)
     27 
     28 //Session 2:
     29 zlm@192.168.56.100:3306 [(none)]>select @@global.innodb_status_output_locks;
     30 +-------------------------------------+
     31 | @@global.innodb_status_output_locks |
     32 +-------------------------------------+
     33 |                                   1 |
     34 +-------------------------------------+
     35 1 row in set (0.00 sec)
     36 
     37 zlm@192.168.56.100:3306 [(none)]>select @@global.innodb_status_output;
     38 +-------------------------------+
     39 | @@global.innodb_status_output |
     40 +-------------------------------+
     41 |                             1 |
     42 +-------------------------------+
     43 1 row in set (0.00 sec)
     44 
     45 zlm@192.168.56.100:3306 [(none)]>select @@autocommit;
     46 +--------------+
     47 | @@autocommit |
     48 +--------------+
     49 |            1 |
     50 +--------------+
     51 1 row in set (0.00 sec)
     52 
     53 zlm@192.168.56.100:3306 [(none)]>begin;select * from t for update;
     54 Query OK, 0 rows affected (0.00 sec)
     55 
     56 ERROR 1046 (3D000): No database selected
     57 zlm@192.168.56.100:3306 [(none)]>begin;select * from zlm.t for update;
     58 Query OK, 0 rows affected (0.00 sec)
     59 
     60 ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction //Wait for 50 seconds(by default) then becomes timeout.
     61 zlm@192.168.56.100:3306 [(none)]>
     62 
     63 //Check the lock information in error log.
     64 [root@zlm1 04:02:10 /data/mysql/mysql3306/data]
     65 #tail -f error.log 
     66 
     67 ...
     68 ------------
     69 TRANSACTIONS
     70 ------------
     71 Trx id counter 2996011
     72 Purge done for trx's n:o < 2996003 undo n:o < 0 state: running but idle
     73 History list length 12
     74 LIST OF TRANSACTIONS FOR EACH SESSION:
     75 ---TRANSACTION 2996010, ACTIVE 3 sec starting index read
     76 mysql tables in use 1, locked 1
     77 LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s)
     78 MySQL thread id 244, OS thread handle 140311521974016, query id 9672 zlm1 192.168.56.100 zlm Sending data
     79 select * from zlm.t for update
     80 ------- TRX HAS BEEN WAITING 3 SEC FOR THIS LOCK TO BE GRANTED:
     81 RECORD LOCKS space id 175 page no 3 n bits 72 index GEN_CLUST_INDEX of table `zlm`.`t` trx id 2996010 lock_mode X waiting
     82 Record lock, heap no 2 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
     83  0: len 6; hex 000000000700; asc       ;;
     84  1: len 6; hex 0000002db708; asc    -  ;;
     85  2: len 7; hex a8000002610110; asc     a  ;;
     86  3: len 4; hex 80000001; asc     ;;
     87  4: len 10; hex 61616120202020202020; asc aaa       ;;
     88 
     89 ------------------
     90 TABLE LOCK table `zlm`.`t` trx id 2996010 lock mode IX
     91 RECORD LOCKS space id 175 page no 3 n bits 72 index GEN_CLUST_INDEX of table `zlm`.`t` trx id 2996010 lock_mode X waiting
     92 Record lock, heap no 2 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
     93  0: len 6; hex 000000000700; asc       ;;
     94  1: len 6; hex 0000002db708; asc    -  ;;
     95  2: len 7; hex a8000002610110; asc     a  ;;
     96  3: len 4; hex 80000001; asc     ;;
     97  4: len 10; hex 61616120202020202020; asc aaa       ;;
     98 
     99 ...
    100 ----------------------------
    101 END OF INNODB MONITOR OUTPUT
    102 ============================
    103 ^C
    104 
    105 //Only an "IX" intention lock and an "X" record lock were found.There's no "IS" intention lock any more.
    106 //Intention locks between transactons does not block each other,they don't conflict.Therefore,when session 2 is gonna to get "X" lock(for update),the "IX" intention lock was generated and the "IS" intention in session 1 didn't appear.
    107 //How about reversing the operations in session 1 and session 2?Let's see below.
    108 
    109 //Session 1:
    110 zlm@192.168.56.100:3306 [zlm]>begin;select * from t for update;
    111 Query OK, 0 rows affected (0.00 sec)
    112 
    113 +----+------+
    114 | id | name |
    115 +----+------+
    116 |  1 | aaa  |
    117 |  2 | bbb  |
    118 |  4 | ccc  |
    119 |  6 | fff  |
    120 +----+------+
    121 4 rows in set (0.00 sec)
    122 
    123 //Session 2:
    124 zlm@192.168.56.100:3306 [(none)]>begin;select * from t where name = 'aaa' lock in share mode;
    125 Query OK, 0 rows affected (0.00 sec)
    126 
    127 ERROR 1046 (3D000): No database selected
    128 zlm@192.168.56.100:3306 [(none)]>begin;select * from zlm.t where name = 'aaa' lock in share mode;
    129 Query OK, 0 rows affected (0.00 sec)
    130 
    131 ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
    132 zlm@192.168.56.100:3306 [(none)]>
    133 
    134 //Check the error log.
    135 [root@zlm1 04:31:00 /data/mysql/mysql3306/data]
    136 #tail -f error.log 
    137 
    138 ...
    139 ------------
    140 TRANSACTIONS
    141 ------------
    142 Trx id counter 2996012
    143 Purge done for trx's n:o < 2996003 undo n:o < 0 state: running but idle
    144 History list length 12
    145 LIST OF TRANSACTIONS FOR EACH SESSION:
    146 ---TRANSACTION 2996011, ACTIVE 26 sec
    147 2 lock struct(s), heap size 1136, 5 row lock(s)
    148 MySQL thread id 293, OS thread handle 140311415437056, query id 11463 zlm1 192.168.56.100 zlm
    149 TABLE LOCK table `zlm`.`t` trx id 2996011 lock mode IX
    150 RECORD LOCKS space id 175 page no 3 n bits 72 index GEN_CLUST_INDEX of table `zlm`.`t` trx id 2996011 lock_mode X
    151 Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
    152  0: len 8; hex 73757072656d756d; asc supremum;;
    153 
    154 Record lock, heap no 2 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
    155  0: len 6; hex 000000000700; asc       ;;
    156  1: len 6; hex 0000002db708; asc    -  ;;
    157  2: len 7; hex a8000002610110; asc     a  ;;
    158  3: len 4; hex 80000001; asc     ;;
    159  4: len 10; hex 61616120202020202020; asc aaa       ;;
    160 
    161 Record lock, heap no 3 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
    162  0: len 6; hex 000000000701; asc       ;;
    163  1: len 6; hex 0000002db708; asc    -  ;;
    164  2: len 7; hex a800000261011f; asc     a  ;;
    165  3: len 4; hex 80000002; asc     ;;
    166  4: len 10; hex 62626220202020202020; asc bbb       ;;
    167 
    168 Record lock, heap no 4 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
    169  0: len 6; hex 000000000702; asc       ;;
    170  1: len 6; hex 0000002db708; asc    -  ;;
    171  2: len 7; hex a800000261012e; asc     a .;;
    172  3: len 4; hex 80000004; asc     ;;
    173  4: len 10; hex 63636320202020202020; asc ccc       ;;
    174 
    175 Record lock, heap no 5 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
    176  0: len 6; hex 000000000703; asc       ;;
    177  1: len 6; hex 0000002db721; asc    - !;;
    178  2: len 7; hex 360000012c2a35; asc 6   ,*5;;
    179  3: len 4; hex 80000006; asc     ;;
    180  4: len 10; hex 66666620202020202020; asc fff       ;;
    181  
    182  ...
    183 ----------------------------
    184 END OF INNODB MONITOR OUTPUT
    185 ============================
    186 ^C
    187 
    188 //We've still get merely "IX" intention lock.The different is that there're four "X" record lock genrated by session 1 and they blocks the session 2 to hold shared read lock on those records,becuase "X" record locks confilct with both "X" and "S" record locks.Remember that we have no index key on column "name" and "select ... where name = 'aaa' lock in share mode;" mean to hold all the "S" record locks on the "name" column.
    4. Inert intention locks test.
      1 //Session 1:
      2 zlm@192.168.56.100:3306 [(zlm)]>select @@transaction_isolation;
      3 +-------------------------+
      4 | @@transaction_isolation |
      5 +-------------------------+
      6 | REPEATABLE-READ         |
      7 +-------------------------+
      8 1 row in set (0.00 sec)
      9 
     10 zlm@192.168.56.100:3306 [zlm]>begin;select * from t for update;
     11 Query OK, 0 rows affected (0.00 sec)
     12 
     13 +----+------+
     14 | id | name |
     15 +----+------+
     16 |  1 | aaa  |
     17 |  2 | bbb  |
     18 |  4 | ccc  |
     19 |  6 | fff  |
     20 +----+------+
     21 4 rows in set (0.00 sec)
     22 
     23 //Session 2:
     24 zlm@192.168.56.100:3306 [(zlm)]>select @@transaction_isolation;
     25 +-------------------------+
     26 | @@transaction_isolation |
     27 +-------------------------+
     28 | REPEATABLE-READ         |
     29 +-------------------------+
     30 1 row in set (0.00 sec)
     31 
     32 zlm@192.168.56.100:3306 [(none)]>begin;insert into zlm.t values(5,'eee');
     33 Query OK, 0 rows affected (0.00 sec)
     34 
     35 ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
     36 zlm@192.168.56.100:3306 [(none)]>
     37 
     38 //Check the error log for detail of locks.
     39 [root@zlm1 04:51:25 /data/mysql/mysql3306/data]
     40 #tail -f error.log 
     41 
     42 ...
     43 ------------
     44 TRANSACTIONS
     45 ------------
     46 Trx id counter 2996022
     47 Purge done for trx's n:o < 2996020 undo n:o < 0 state: running but idle
     48 History list length 15
     49 LIST OF TRANSACTIONS FOR EACH SESSION:
     50 ---TRANSACTION 2996021, ACTIVE 13 sec inserting
     51 mysql tables in use 1, locked 1
     52 LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s) //The two lock structs were intention lock("IX") and insert intention lock.
     53 MySQL thread id 318, OS thread handle 140311522375424, query id 12700 zlm1 192.168.56.100 zlm update
     54 insert into zlm.t values(5,'eee')
     55 ------- TRX HAS BEEN WAITING 13 SEC FOR THIS LOCK TO BE GRANTED:
     56 RECORD LOCKS space id 175 page no 3 n bits 72 index GEN_CLUST_INDEX of table `zlm`.`t` trx id 2996021 lock_mode X insert intention waiting
     57 Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
     58  0: len 8; hex 73757072656d756d; asc supremum;; //Session 1 holds all "X" record locks of table "t".So it showed supremum what means the gap is infinite and no record can be inserted into the table at all.
     59 
     60 ------------------
     61 TABLE LOCK table `zlm`.`t` trx id 2996021 lock mode IX //The "IX" intention lock of session 2.
     62 RECORD LOCKS space id 175 page no 3 n bits 72 index GEN_CLUST_INDEX of table `zlm`.`t` trx id 2996021 lock_mode X insert intention waiting
     63 Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
     64  0: len 8; hex 73757072656d756d; asc supremum;;
     65 
     66 ---TRANSACTION 2996020, ACTIVE 255 sec
     67 2 lock struct(s), heap size 1136, 5 row lock(s)
     68 MySQL thread id 316, OS thread handle 140311522174720, query id 12450 zlm1 192.168.56.100 zlm
     69 TABLE LOCK table `zlm`.`t` trx id 2996020 lock mode IX //The "IX" intention lock of session 1.
     70 RECORD LOCKS space id 175 page no 3 n bits 72 index GEN_CLUST_INDEX of table `zlm`.`t` trx id 2996020 lock_mode X
     71 Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
     72  0: len 8; hex 73757072656d756d; asc supremum;;
     73 
     74 Record lock, heap no 2 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
     75  0: len 6; hex 000000000700; asc       ;;
     76  1: len 6; hex 0000002db708; asc    -  ;;
     77  2: len 7; hex a8000002610110; asc     a  ;;
     78  3: len 4; hex 80000001; asc     ;;
     79  4: len 10; hex 61616120202020202020; asc aaa       ;;
     80 
     81 Record lock, heap no 3 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
     82  0: len 6; hex 000000000701; asc       ;;
     83  1: len 6; hex 0000002db708; asc    -  ;;
     84  2: len 7; hex a800000261011f; asc     a  ;;
     85  3: len 4; hex 80000002; asc     ;;
     86  4: len 10; hex 62626220202020202020; asc bbb       ;;
     87 
     88 Record lock, heap no 4 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
     89  0: len 6; hex 000000000702; asc       ;;
     90  1: len 6; hex 0000002db708; asc    -  ;;
     91  2: len 7; hex a800000261012e; asc     a .;;
     92  3: len 4; hex 80000004; asc     ;;
     93  4: len 10; hex 63636320202020202020; asc ccc       ;;
     94 
     95 Record lock, heap no 5 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
     96  0: len 6; hex 000000000703; asc       ;;
     97  1: len 6; hex 0000002db721; asc    - !;;
     98  2: len 7; hex 360000012c2a35; asc 6   ,*5;;
     99  3: len 4; hex 80000006; asc     ;;
    100  4: len 10; hex 66666620202020202020; asc fff       ;;
    101  
    102  ...
    103 ----------------------------
    104 END OF INNODB MONITOR OUTPUT
    105 ============================
    106 ^C
    107 
    108 //Session 2 meant to get an insert intention lock when it was executing "insert into xxx" but waited until timeout.
    109 //Whatif we only lock a certain record,what will session do then?Let's see below.
    110 
    111 //Session 1:
    112 zlm@192.168.56.100:3306 [zlm]>begin;select * from t where id=4 for update;
    113 Query OK, 0 rows affected (0.00 sec)
    114 
    115 +----+------+
    116 | id | name |
    117 +----+------+
    118 |  4 | ccc  |
    119 +----+------+
    120 1 row in set (0.00 sec)
    121 
    122 //Session 2:
    123 zlm@192.168.56.100:3306 [(none)]>begin;insert into zlm.t values(3,'ccc');
    124 ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
    125 zlm@192.168.56.100:3306 [(none)]>
    126 
    127 //Check error log again.
    128 [root@zlm1 05:06:19 /data/mysql/mysql3306/data]
    129 #tail -f error.log 
    130 
    131 ...
    132 ------------
    133 TRANSACTIONS
    134 ------------
    135 Trx id counter 2996025
    136 Purge done for trx's n:o < 2996020 undo n:o < 0 state: running but idle
    137 History list length 15
    138 LIST OF TRANSACTIONS FOR EACH SESSION:
    139 ---TRANSACTION 2996024, ACTIVE 9 sec inserting
    140 mysql tables in use 1, locked 1
    141 LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s), undo log entries 1
    142 MySQL thread id 376, OS thread handle 140311521974016, query id 14398 zlm1 192.168.56.100 zlm update
    143 insert into zlm.t values(3,'ccc')
    144 ------- TRX HAS BEEN WAITING 9 SEC FOR THIS LOCK TO BE GRANTED:
    145 RECORD LOCKS space id 175 page no 4 n bits 72 index id of table `zlm`.`t` trx id 2996024 lock_mode X locks gap before rec insert intention waiting
    146 Record lock, heap no 4 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
    147  0: len 4; hex 80000004; asc     ;;
    148  1: len 6; hex 000000000702; asc       ;;
    149 
    150 ------------------
    151 TABLE LOCK table `zlm`.`t` trx id 2996024 lock mode IX
    152 RECORD LOCKS space id 175 page no 4 n bits 72 index id of table `zlm`.`t` trx id 2996024 lock_mode X locks gap before rec insert intention waiting
    153 Record lock, heap no 4 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
    154  0: len 4; hex 80000004; asc     ;;
    155  1: len 6; hex 000000000702; asc       ;;
    156 
    157 ---TRANSACTION 2996023, ACTIVE 28 sec
    158 4 lock struct(s), heap size 1136, 3 row lock(s)
    159 MySQL thread id 374, OS thread handle 140311415437056, query id 14377 zlm1 192.168.56.100 zlm
    160 TABLE LOCK table `zlm`.`t` trx id 2996023 lock mode IX
    161 RECORD LOCKS space id 175 page no 4 n bits 72 index id of table `zlm`.`t` trx id 2996023 lock_mode X
    162 Record lock, heap no 4 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
    163  0: len 4; hex 80000004; asc     ;;
    164  1: len 6; hex 000000000702; asc       ;;
    165 
    166 RECORD LOCKS space id 175 page no 3 n bits 72 index GEN_CLUST_INDEX of table `zlm`.`t` trx id 2996023 lock_mode X locks rec but not gap
    167 Record lock, heap no 4 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
    168  0: len 6; hex 000000000702; asc       ;;
    169  1: len 6; hex 0000002db708; asc    -  ;;
    170  2: len 7; hex a800000261012e; asc     a .;;
    171  3: len 4; hex 80000004; asc     ;;
    172  4: len 10; hex 63636320202020202020; asc ccc       ;;
    173 
    174 RECORD LOCKS space id 175 page no 4 n bits 72 index id of table `zlm`.`t` trx id 2996023 lock_mode X locks gap before rec
    175 Record lock, heap no 5 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
    176  0: len 4; hex 80000006; asc     ;;
    177  1: len 6; hex 000000000703; asc       ;;
    178 
    179 //The locks seem to be more and more complicated.
    180 //Session 1(TRANSACTION 2996023) holded an "IX" intention lock,a "X" record lock,two gap locks.
    181 //Session 2(TRANSACTION 2996024) asked for holded an "IX" intention lock and asked for an intert intention lock which was relevant with the gap before the record it meant to insert.The transaction of session 2 waited until timeout.
    Summary
    • intention locks are table-level locks created by InnoDB automatically when we have intentions to modify a certain record(or some of relevant records) in these tables.
    • The main effect of intention locks is to make InnoDB be more compatible in multidimensional lock granularity(both table-level and row-level locks).
    • It can simplify the mechanism in checking record locks of a certain table.For exmple,MySQL don't need to retrieve the full table when a client(or session) is modifying(or going to modify) records in that table.
    • The variables "innodb_status_output_locks" should be set "on",if we want to see them in the output of "show engine innodb status" statement.
    • Insert intention locks is similar with intention locks but it's merely relevant with those insert operations.

  • 相关阅读:
    堆排序
    上线打包不常见错误整理
    ios开发者相关的几个apple邮箱
    App被拒选择回复还是重新提审,如何选择最高效的应对方式?
    iOS证书(.p12)和描述文件(.mobileprovision)申请
    OC与Swift混编
    tableViewCell重用
    tabBar选择不同item设置标题不同颜色
    iOS 关于TouchID指纹解锁的实现
    cocoaPods报错You need at least git version 1.8.5 to use CocoaPods
  • 原文地址:https://www.cnblogs.com/aaron8219/p/9471683.html
Copyright © 2011-2022 走看看