Desmond Stonie

Results 10 comments of Desmond Stonie

会出现死锁吗?能否提供下 test 表的初始数据?

死锁日志里只能看到死锁发生时两个事务当前正在执行的SQL,这两个SQL不一定冲突,看事务一 `undo log entries 10` 说明事务一在执行这个SQL之前还有其他的SQL,和事务二冲突了,所以要检查下业务代码逻辑,或者查查binlog看看日志。

死锁日志里能看到事务二加锁的记录是:`(id, resource_id, type, corp_id) = ('2c908a266ee67a45016ee693ab4642', 'c5d957168ad046fbacb6be58a8edd5', 'C', '23288')`,加锁类型是记录锁(lock_mode X locks rec but not gap),而事务一也要对这条记录加锁,加锁类型是 NK 锁(lock mode S),所以阻塞,要分析下事务一为什么会对这条记录加 S 锁。 另外,事务二还要对另一个记录加锁,`(id, resource_id, type, corp_id) = ('2c908a266ee67a45016ee693b31844', '2a641e55bbde4bebb0b2018324fc49', 'D', '9434')`,这条记录的...

可以看下哪里有删除 9434 的地方,如果你非常肯定事务一没有删这条记录,那也有可能是三个事务连锁导致的死锁。binlog里找下这个时间点前后的日志,应该可以看到DELETE语句。 另外,你说两个事务都仅有插入操作,那么事务一在等待的S锁就只可能有一种情况:出现了唯一键冲突。binlog里找下是不是有其他事务也执行了插入操作?

你好,谢谢你提供的死锁案例,从你的死锁日志可以抽出下面大概的信息: 事务一: ``` INSERT INTO `account_user_groups` (`user_id`, `group_id`) VALUES (113, 704) WAITING space id 6655 page no 255 lock mode S waiting ``` 事务二: ``` DELETE FROM `account_user_groups` WHERE `account_user_groups`.`group_id`...

> 为了避免死锁,事务首句有 select .. for update 的语句,保证对 group_id 相同的记录,只有一个事务正在更新 这个 select .. for update 语句是什么样的?针对所有的 g1 g2 ... 都加锁吗?

能否提供下两个事务具体的 SQL?

一般来说有几种方法可以避免这个死锁: 1. 代码中尽量不要出现 delete 某个 key 然后又插入相同 key 的场景,可以改成 `INSERT ... ON DUPLICATE KEY UPDATE`; 2. 将这个 key 改成非唯一索引; 3. 使用锁实现串行化处理,譬如你使用分布锁,或者在 DELETE 之前,先执行 `SELECT * FROM test_table WHERE id =...

不知道你的重现步骤是怎么样的?我之前有重现过案例18,你可以看下这个脚本,README 里写了我的重现步骤:https://github.com/aneasystone/mysql-deadlocks/blob/master/docker/db/t18.sql

好的,谢谢建议,最近正好打算重新维护下这个项目,到时候会把 MySQL 版本也考虑进来。