一、MySQL锁的分类
1、全局锁
- 锁定整个数据库,使其处于只读状态。
- 使用场景:全库备份等需要确保数据一致性的场景
- 示例命令:
FLUSH TABLES WITH READ LOCK;
在执行此命令后,所有写操作都会被阻塞,直到锁被释放。
2、表级锁
- 对某个表加锁,包括表锁和元数据锁
- 表锁分为读锁(共享锁)和写锁(排他锁)。表级锁是粗粒度的锁,适用于不需要并发操作的场景。
- MDL在对表结构进行修改时会自动加锁,保护表的元数据信息。
3、意向锁(Intention Lock)
- 表级锁的一致,标记当前事务对表中行的锁定意图。用于加速表锁和行锁之间的协调。
- 分为意向共享锁(IS)和意向排他锁(IX)意向锁自身不会阻塞其他事务,但与表锁配合使用可以提升锁定效率。
4、AUTO-INC锁
- 专门用于AUTO_INCREMENT字段的锁,确保自增列的唯一性和顺序性。
- 当插入自增列数据时,MySQL会对表加一个短暂的锁,保证多线程插入时自增列的正确性。
- 这种锁的优势在于临时锁定,在插入完成后立即释放,并不阻塞其他类型操作。
5、行级锁
- MySQL中最细粒度的锁,允许对单行记录进行加锁。主要用于InnoDB存储引擎,极大地提升了并发性能。
- 包括:
- Record Lock(记录锁):锁定单行记录
- Gap Lock(间隙锁):锁定一个范围(间隙),防止插入新记录,避免幻读。
- Next-Key Lock(临建锁):结合记录锁和间隙锁,锁定记录及其间隙,是InnoDB默认的行锁机制。
- 插入意向锁(Insert Intention Lock):事务准备插入某行前会加此锁,多个事务插入不同位置的记录时不会互相阻塞。
为什么需要AUTO-INC锁,而不是直接使用表锁?
表锁粒度过大,会锁定整个表,导致并发性能下降。而AUTO-INC锁是一种短暂的锁,仅在分配自增列时加锁,插入完成后立即释放,不会阻塞其他读写操作,性能更好。
总结
- 选择合适的锁粒度:在高并发场景中,尽量使用行级锁来减少锁冲突,提升并发性能。
- 全局锁和表锁要慎用:在需要全库或全表操作时,应合理使用全局锁和表锁,避免长时间阻塞其他操作。
- 关注隔离级别:了解事务隔离级别对锁机制的影响,选择合适的隔离级别以避免不必要的锁竞争和性能损耗。