MySQL InnoDB死锁

问题描述 投票:0回答:1

例如:

交易1:select 'row 1' (s lock);

交易2:update 'row 1'(x lock);

交易1:update 'row 1'(x lock);

比事务2会死锁。

我不明白为什么innodb x锁必须等待先前的x锁(对于同一行,然后等待)释放?我认为事务2的x锁定实际上从未锁定过row1。并且事务1在行1上已经具有唯一的s锁。因此,我认为不必等待来自事务2的x锁定就可以进行事务1的更新操作。

mysql innodb deadlock
1个回答
1
投票

[SELECT FOR UPDATE获得X锁,而不是S锁。

您的示例中的事务2等待事务1。您可以通过以下方式查看它:

mysql> select * from sys.innodb_lock_waits\G
*************************** 1. row ***************************
                wait_started: 2019-12-26 00:33:04
                    wait_age: 00:00:17
               wait_age_secs: 17
                locked_table: `test`.`mytable`
         locked_table_schema: test
           locked_table_name: mytable
      locked_table_partition: NULL
   locked_table_subpartition: NULL
                locked_index: PRIMARY
                 locked_type: RECORD
              waiting_trx_id: 5651
         waiting_trx_started: 2019-12-26 00:33:04
             waiting_trx_age: 00:00:17
     waiting_trx_rows_locked: 1
   waiting_trx_rows_modified: 0
                 waiting_pid: 9
               waiting_query: update mytable set id = 2 where id = 1
             waiting_lock_id: 4878281352:36:4:2:140455975282712
           waiting_lock_mode: X,REC_NOT_GAP
             blocking_trx_id: 5650
                blocking_pid: 8
              blocking_query: select * from sys.innodb_lock_waits
            blocking_lock_id: 4878280464:36:4:2:140455975278104
          blocking_lock_mode: X,REC_NOT_GAP
        blocking_trx_started: 2019-12-26 00:32:49
            blocking_trx_age: 00:00:32
    blocking_trx_rows_locked: 1
  blocking_trx_rows_modified: 0
     sql_kill_blocking_query: KILL QUERY 8
sql_kill_blocking_connection: KILL 8

注意blocking_lock_mode是X,而不是S。

事务1在您的示例中不等待,它只是更新了该行,因为它已被锁定。

事务2不会死锁。如果事务1不久不释放其锁,它最终将超时。这不是死锁,因为事务1没有等待事务2。

© www.soinside.com 2019 - 2024. All rights reserved.