MySQL 死锁:产生原因、分析与解决

MySQL 死锁:产生原因、分析与解决 在高并发系统中,数据库死锁是比较常见的问题。 很多开发者第一次遇到死锁时,会认为: 数据库是不是出问题了? 实际上,死锁本身并不意味着 MySQL 出现了故障。对于 InnoDB 来说,死锁是并发事务之间形成循环等待后,由存储引擎主动检测并处理的一种正常机制。 真正需要解决的问题不是简单地“关闭死锁”,而是: 为什么会产生死锁? 哪些 SQL 导致了循环等待? 为什么某个事务被回滚? 如何从根本上减少死锁? 应用程序收到死锁异常后应该怎么处理? 理解这些问题,才能正确处理生产环境中的死锁。 1. 什么是死锁 死锁(Deadlock)是指两个或多个事务互相持有对方需要的锁,同时等待对方释放锁,最终形成循环等待。 例如有两个账户: 账户 1 账户 2 事务 A: 锁住账户 1 ↓ 等待账户 2 事务 B: 锁住账户 2 ↓ 等待账户 1 最终形成: 事务 A → 等待事务 B 持有的锁 事务 B → 等待事务 A 持有的锁 这就是典型的死锁。 需要注意,死锁和锁等待不是一回事。 普通锁等待可能是: 事务 A 持有锁 ↓ 事务 B 等待事务 A 只要事务 A 最终提交或回滚,事务 B 就可以继续执行。...

2023年11月13日 · 5 min · Leanku

MySQL InnoDB 锁机制详解

MySQL InnoDB 锁机制详解 在并发业务中,多个事务可能同时修改或者读取相同的数据。如果没有并发控制,就可能出现脏写、数据覆盖、幻读等问题。 InnoDB 通过锁机制和 MVCC 等机制共同实现事务的并发控制。 例如两个事务同时修改同一条订单: UPDATE orders SET status = 2 WHERE id = 100; 如果事务 A 尚未提交,事务 B 同时执行相同的 UPDATE,那么事务 B 通常不能立即完成,而是需要等待事务 A 释放相关锁。 因此,理解 InnoDB 锁机制,对于分析以下问题非常重要: 为什么 UPDATE 会等待? 为什么 SELECT 有时候也会加锁? 为什么一个 UPDATE 影响了一行,却可能产生多个锁? 为什么会出现 Gap Lock? 为什么会发生死锁? 1. InnoDB 为什么需要锁 假设账户余额为: balance = 1000 事务 A: UPDATE accounts SET balance = balance - 100 WHERE id = 1; 同时事务 B: UPDATE accounts SET balance = balance - 200 WHERE id = 1; 如果两个事务完全不进行并发控制,就可能发生:...

2023年07月21日 · 4 min · Leanku