有人能解释我的mysql死锁情况吗?

有人能解释我的mysql死锁情况吗?,mysql,insert,deadlock,Mysql,Insert,Deadlock,我有几个关于mysql死锁的问题 我不明白为什么下面的insert查询会进入死锁状态。 两者都是相同的查询,但具有不同的主键值和唯一的键值。(必须是不同的行) 我的问题是 为什么TX1在插入时需要表上的S锁 为什么它们需要相同的锁?(id 1126第1121626页n位240索引ix_1) 我的理解是 TX2在更新位置上获得X锁 TX1希望得到与TX2相同的锁。所以TX1正在等待 TX2希望获得与gap相同的锁。为什么它也需要间隙锁 有人能解释我的问题吗? mysql死锁检测器如下所示

我有几个关于mysql死锁的问题

我不明白为什么下面的insert查询会进入死锁状态。 两者都是相同的查询,但具有不同的主键值和唯一的键值。(必须是不同的行)

我的问题是

  • 为什么TX1在插入时需要表上的S锁
  • 为什么它们需要相同的锁?(id 1126第1121626页n位240索引ix_1)
  • 我的理解是
    • TX2在更新位置上获得X锁
    • TX1希望得到与TX2相同的锁。所以TX1正在等待
    • TX2希望获得与gap相同的锁。为什么它也需要间隙锁
  • 有人能解释我的问题吗?


    mysql死锁检测器如下所示

     (1) TRANSACTION:
    
    TRANSACTION 61201547464, ACTIVE 1 sec inserting mysql tables in use 1, locked 1 LOCK WAIT 7 lock struct(s), heap size 1184, 5 row lock(s), undo log entries 3 MySQL thread id 5551783, OS thread handle 0x2b463b79d700, query id 100234460104 192.168.0.4 dbuser update 
    insert into deadlocktable (a, b, c, d, e, id) values (1, 1453004563, 'gerg354g3g54fgrg45g4rgt4t4t4ft4f4fff', '23r23r232rr23r23r3refserwewfswe', 22342432343, 'sdlkfj30fji0')
    
    (1) WAITING FOR THIS LOCK TO BE GRANTED:
    
    RECORD LOCKS space id 1126 page no 1121626 n bits 240 index `ix_1` of table `mydb`.`deadlocktable` trx id 61201547464 lock mode S waiting Record lock, heap no 170 PHYSICAL RECORD: n_fields 3; compact format; info bits 32
     0: len 8; hex 0000092f98cc6435; asc    /  d5;;
     1: len 30; hex 234385385390853853858423584235930485923085892305842390843048; asc skfjskfjsdkfjsdkfjsdkfdjskfdkf; (total 36 bytes);
     2: len 30; hex 344375894375389475894353894897539847589375893748953745738945; asc sdklfjskldfjsdkfjsklfsdklfjsdk; (total 36 bytes);
    
    (2) TRANSACTION:
    
    TRANSACTION 61201547752, ACTIVE 1 sec inserting, thread declared inside InnoDB 5000 mysql tables in use 1, locked 1
    7 lock struct(s), heap size 1184, 6 row lock(s), undo log entries 3 MySQL thread id 5550461, OS thread handle 0x2b4642d2c700, query id 100234460128 192.168.168.7 dbuser update 
    insert into deadlocktable (a, b, c, d, e, id) values (1, 1453004563, 'skfjskfjsdkfjsdkfjsdkfdjskfdkffd', 'erg34geg4ewg34fg4g4g4grffsdfew', 34343t6543343, 'dfsdggrg')
    
    (2) HOLDS THE LOCK(S):
    
    RECORD LOCKS space id 1126 page no 1121626 n bits 240 index `ix_1` of table `mydb`.`deadlocktable` trx id 61201547752 lock_mode X locks rec but not gap Record lock, heap no 170 PHYSICAL RECORD: n_fields 3; compact format; info bits 32
     0: len 8; hex 0000092f98cc6435; asc    /  d5;;
     1: len 30; hex 234385385390853853858423584235930485923085892305842390843048; asc skfjskfjsdkfjsdkfjsdkfdjskfdkf; (total 36 bytes);
     2: len 30; hex 344375894375389475894353894897539847589375893748953745738945; asc sdklfjskldfjsdkfjsklfsdklfjsdk; (total 36 bytes);
    
     (2) WAITING FOR THIS LOCK TO BE GRANTED:
    
    RECORD LOCKS space id 1126 page no 1121626 n bits 240 index `ix_1` of table `mydb`.`deadlocktable` trx id 61201547752 lock_mode X locks gap before rec insert intention waiting Record lock, heap no 170 PHYSICAL RECORD: n_fields 3; compact format; info bits 32
    
     0: len 8; hex 0000092f98cc6435; asc    /  d5;;
     1: len 30; hex 234385385390853853858423584235930485923085892305842390843048; asc skfjskfjsdkfjsdkfjsdkfdjskfdkf; (total 36 bytes);
     2: len 30; hex 344375894375389475894353894897539847589375893748953745738945; asc sdklfjskldfjsdkfjsklfsdklfjsdk; (total 36 bytes);
    
    表架构是

    CREATE TABLE `deadlocktable` (
      `id` varchar(36) NOT NULL,
      `c` char(36) NOT NULL,
      `b` int(11) NOT NULL DEFAULT '0',
      `a` tinyint(1) NOT NULL DEFAULT '1',
      `d` varchar(50) DEFAULT 'defaultSessionId',
      `e` bigint(15) unsigned zerofill NOT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `ix_1` (`e`,`c`),
      KEY `ix_2` (`b`),
      KEY `ix_3` (`c`),
      KEY `ix_4` (`e`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1 
    

    |

    尝试将隔离级别更改为
    READ-COMMITTED
    @Vatev谢谢您的建议。但是,我希望在同时插入不同的行时找到锁定机制。在弄清楚它是如何工作的之后,让我试试你的建议。@Vatev建议这样的解决方案时,不要不提到它的巨大影响。恐怕这是一个很糟糕的建议。
    CREATE TABLE `deadlocktable` (
      `id` varchar(36) NOT NULL,
      `c` char(36) NOT NULL,
      `b` int(11) NOT NULL DEFAULT '0',
      `a` tinyint(1) NOT NULL DEFAULT '1',
      `d` varchar(50) DEFAULT 'defaultSessionId',
      `e` bigint(15) unsigned zerofill NOT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `ix_1` (`e`,`c`),
      KEY `ix_2` (`b`),
      KEY `ix_3` (`c`),
      KEY `ix_4` (`e`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1