MySQL 有哪些锁?
全局锁 表级锁
1 全局锁
- 状态:使用全局锁后,整个数据库处于只读状态。对内容和表结构的增删改都不能进行
- 作用:主要用于全库逻辑备份 备份期间不会出现更新导致备份与预期不一样
- 缺点:备份会花很长时间,导致业务停滞
- 措施:对于支持可重复读的隔离级别,备份前开启事务 创建ReadView 其他业务正常进行
2 表级锁
表锁、元数据锁、意向锁、AUTO-INC锁
2.1 表锁
对表加锁后,会限制本线程和其他线程的读写操作 但是颗粒度太大,会影响并发性能,尽量避免使用表锁
2.2 元数据锁(MDL)
- 元数据锁不需要主动使用,当我们对表进行CRUD,自动加MDL读锁;对表结构更改,自动加MDL写锁
- MDL在事务提交后自动释放。如果一个事务迟迟没有提交,会出问题。导致其他线程的请求一直在等待
2.3 意向锁
先解释下两个概念
- 共享锁:共享锁可以被多个线程持有,获得共享锁的可以读数据,但是不能改数据。也就是允许你读也允许别人读。但加了共享锁,别人就不能加独占锁(排他)我先要读的,你可以来读,但是不允许你写
- 独占锁:独占锁被单个线程所持有,获得独占锁的可以读也可以写数据。但是不能同时被其他线程共享和独占。 要写只能我自己写,别人不能看,也不能写
接着说意向锁: - 在使用InnoDB引擎对表记录加【共享锁】之前,需要先在表级别上加一个【意向共享锁】
- 在使用InnoDB引擎对表记录加【独占锁】之前,需要先在表级别上加一个【意向独占锁】
- 意向共享锁和意向独占锁是表级锁,不会和行级的锁冲突。而且意向锁之间也不会冲突(意向而已)只会和共享表锁和独占表锁冲突
- 满足:读读共享、读写互斥、写写互斥
意向锁的作用在于:如果没有意向锁,那么在加独占表锁之前,需要遍历表的记录,查看是否有独占锁,效率很慢。有了意向锁,在加独占锁之前,先对所在的表加意向独占锁。那么其他锁来的时候之间就能看到是否有记录被加了独占锁,不用遍历。(一家有阳,整个村子先列为风险区 别人看到就知道有阳 不用挨家挨户看有没有阳) 意向锁的目的是为了快速判断表里是否有记录被加锁
2.4 AUTO-INC锁
- 用来保证自增实现。执行AUTO-INC锁的过程中,其他事务要向表中插入数据的操作都会被阻塞,从而保证连续递增
- 不再是事务提交后才释放,而是执行完插入语句后自动释放锁。
- 缺点:对于大量插入,影响性能 所以提供了轻量级的锁来完成,会在递增字段枷锁,赋一个递增值,就释放。不需要等待整个插入完成。
3 行级锁
- 记录锁(Record Lock): 锁住的是一条记录 其他事务无法修改 也分XS
- 间隙锁(Gap Lock):对范围记录加锁,这一其他事务无法插入记录,有效防止幻读
- 临键锁(Next-Key Lock)是上面两个的组合 锁定范围也锁定记录本事 (3,5】锁则不能插入4 也不能修改5
- 插入意向锁:插入记录时要判断是否被加了间隙锁,插入意向锁是行级别的,表明我下一步要插入,但目前在等待,它不是意向锁 。比如A设置间隙锁(35 )B想插入4 等A结束才行 它锁住的是一个点4 而不是区间
|