目录
mysql会在什么情况下加什么锁?
不同sql加的锁
- select …快照读,不加锁
- select … lock in share mode,当前读,加S锁
- select …for update,当前度,加X锁
- DML语句,如insert、delete、update,当前读,加X锁
- 常见DDL语句,如alter、create等,加表级锁,且这些语句为隐式提交,不能回滚
不同数据加的锁
聚簇索引,查询命中
记录排他锁
聚簇索引,查询未命中
RC级别不加锁
RR级别会加间隙锁
二级唯一索引,命中
两个索引树都会加记录锁
二级唯一索引,未命中
查询ISBN = ‘N0008’ ,加间隙锁
二级非唯一索引,命中
RC级别下:记录锁
RR级别下:临键锁:Next-Key
二级非唯一索引,未命中
RC级别下不加锁
无索引
当where 条件不走索引时,则会进行全表扫描,锁全表
聚簇索引,范围查询
where id <= 25时,怎么加锁?
二级索引,范围查询
where score <= 7.9
修改索引值时
update table set author= ‘’ where id = 10
除了在主键索引10上加记录锁,还会锁二级索引树上 id = 10 对应的值
delete语句加锁
delete和select for update、update没有太大差异
在mysql数据库中,执行delete语句是,并没有进行物理删除,而是打上一个删除记录,然后通过一个叫purge的后台线程清理。
insert加锁
insert在两种情况下会加锁
- 防止幻读,记录之间有间隙锁,则此时不能insert
- insert的记录和已有记录冲突,不能insert
除了上述情况,insert的锁都是隐式的,隐式锁是innodb实现的一种延迟加锁的机制来减少锁的数据量的。
隐式锁的特点是,可能发生冲突了才加锁,减少了锁的数量
insert的加锁流程:
- 对插入的间隙加插入意向锁(II Gap),如果该间隙有间隙锁或临键锁,则阻塞,没有则成功,可以插入。
- 判断是否有唯一键,进行唯一性检查,有则判断该键是否有加锁,如果没有锁,则判断该记录是否被标记删除,有标记则说明是purge线程还未及时清理,此时加S锁等待。如果没有标记删除,则报错duplicate key。如果有锁则加S锁等待
- 插入记录并加X记录锁