MySQL 8.0.28切换隔离级别后行删除行为是否存在差异?
在MySQL 8.0.28中切换隔离级别对批量删除操作的行为差异分析
是的,将隔离级别从默认的可重复读(Repeatable Read)切换为读已提交(Read Committed)后,批量删除操作的行为存在显著差异,核心原因在于两种隔离级别的锁机制与一致性视图逻辑不同,结合你的场景具体分析如下:
可重复读(Repeatable Read)下死锁的根源
- 可重复读隔离级别中,事务启动时会生成全局一致性快照,删除操作需要扫描所有符合
StartTime <= CURTIME() - INTERVAL 20 DAY条件的行,并为每一行加排他锁(X锁)。 - 由于目标表
testdb.operationtable持续有查询(Select)请求,查询会持有共享锁(S锁),加上表包含7个索引,锁冲突的概率被大幅放大。 - 更关键的是,可重复读模式下InnoDB会启用间隙锁+临键锁机制,锁范围会覆盖符合条件的行及相邻间隙,进一步加剧锁竞争。当大量行锁与查询的共享锁冲突时,死锁检测机制会触发,将删除事务判定为死锁牺牲品并终止。
读已提交(Read Committed)下的行为变化
- 读已提交隔离级别取消了间隙锁(仅外键约束和唯一索引场景保留),仅使用记录锁,锁范围仅限定在实际要删除的行上,锁竞争概率大幅降低。
- 该隔离级别下,事务每次执行语句时都会生成新的一致性快照,删除操作不会因快照保留不必要的锁,锁的持有时间更短。
- 当批量删除的行数(100万行)占表总数据量(700万行)比例较高时,MySQL会自动将行锁升级为表锁——因为维护大量行锁的开销远大于直接持有表锁,这也避免了逐行锁带来的冲突,最终能在约2分钟内完成删除操作。
场景补充说明
- 目标表
testdb.operationtable无分区设计,批量删除只能全表扫描或走StartTime索引扫描;7个索引会导致删除时需要额外维护索引数据,进一步增加锁竞争的可能性。 - 执行的删除语句:
DELETE FROM testdb.operationtable WHERE StartTime <= CURTIME() - INTERVAL 20 DAY;
内容的提问来源于stack exchange,提问作者Rahul G
相关产品推荐
相关产品推荐

