目录
1.索引上的等值查询(唯一索引)给不存在的记录加锁时,优化为间隙锁
锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的计算资源(CPU,RAM,IO)的争用以外,数据也是一种共许多用户共享的资源。如何保证数据并发发访问的一致性,有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访
问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。
1.全局锁
全局锁就是对整个数据库实例加锁,加锁后整个实例就处于只读状态,后续的DML的写语句,DDL语句,已经更新提作的事务提交语句都将被阻塞。
全局锁典型的使用场景就是做全库的逻辑备份,对所有的表进行锁定,从而获取一致性视图,保证数据的完整性。
1.1加锁逻辑备份和释放锁语法
对于整个库加锁:flush tables with read lock;
释放锁:unlock tables;
对于全库逻辑备份:mysqldump -u [用户名] -p [密码] --all-databases > [备份文件名].sql
1.2全局锁的劣势
对于数据库加全局锁,是一个比较重的操作
- 如果再重主库上备份,那么备份期间都不能执行更新,业务基本停摆
- 如果再从库上备份,那么备份期间从库不能执行主库同步过来的二级制日志,导致主从延迟
2.表级锁
每次操作锁住整张表,锁定颗粒度大,发生冲突概率最高,并发度最低
2.1表级锁
对于表锁,分两类
- 表共享读锁
- 表独占写锁
语法:1.加锁:lock tables 表名 read/write 2.释放锁:unlock tables/客户端断开连接
情况一:
客户端一添加读锁
客户端二查询数据成功
情况二:
客户端一加写锁
客户端二查询数据失败
2.1.1总结
读锁不会阻塞其他客户端的读,但是会阻塞写。写锁及会阻塞其他客户端的读,也会阻塞其他客户端的写
2.2元数据锁(meta data lock,MDL)
元数据:可以看成一张表
MDL加锁过程是系统自动控制,无需显式使用,在访问一张表的时候会自动加上。MDL锁主要作用是维护表元数据一致性,在表
,上有活动事务的时候,不可以对元数据进行写入操作。为了避免DML与DDL冲突,保证读写的正确性。DML:用于对数据库中的数据进行操作,像插入、更新、删除和查询等操作都涵盖在内
DDL:对数据库的结构进行定义和管理,包括创建、修改和删除数据库对象,例如表、视图、索引等.
2.2.1总结
对于DML操作插入,删除,查询表中的数据互相兼容,对数据库结构操作失败
客户端一:开启事务进行查询语句
客户端二:更新数据
操作库表:为该库表添加一个字段失败
2.3意向锁
1.意向共享锁(is): 由语句 select...lock in share mode添加。
2.意向排他锁(ix):由insert,update,delete,select....for update 添加。注意:意向排它锁不需要我们手动添加只需要开启事务,执行相应的语句就自动开启,共享锁需要在执行语句后面添加lock in share mode
可以通过以下sql,查看意向锁及行锁的加锁情况:
select object schema_object ,name_ndex,name_object ,tyoe,lock_mode,iock_ data from performance schemadata
客户端一添加共享锁
客户端二添加读锁和写锁区别
2.3.1总结
意向共享锁与读锁兼容,与写锁互斥。意向互斥锁与读锁写锁互斥。
3.行级锁
每次操作锁住对应的行数据,锁定粒度最小,发生锁冲突的概率最低,并发度最高。应用在InnoDB存储引擎当中
3.1行锁
InnoDB实现了两种类型的锁:
1.共享锁:允许一个事务去读取一行,阻止其他事务获取相同数据集的排它锁
2.排它锁:允许获取牌太怂的事务更新数据,阻止其他事务获得相同数据集的共享锁和排它锁
以通过一下sql查看意向锁以及行锁的枷锁情况:
select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_locks;
对于客户端一和客户端二进行加共享锁都成功
3.1.1总结
1.针对索引进行检索时,对已存在的记录进行等值匹配时,将自动优化为行锁
2.InnoDB的行锁是针对于索引加的锁,不通过索引条件检索数据,那么InnoDB将对表中的所有记录加锁,此时就会升级为表锁
3.2间隙锁/临键锁
1.索引上的等值查询(唯一索引)给不存在的记录加锁时,优化为间隙锁
给stu添加一个数据等值匹配id=5,显然不存在,所以mysql自动给8-11(不包含8和11)添加了间隙锁
我们通过命令查看锁,x=排他锁,GAP = 间隙。然后我们往这个间隙插入数据显然卡在那了
2.索引上的等值查询(普通索引),向右遍历时最后一个值不满足查询需求时,next-key lock退化为间隙锁
3.索引上的范围查询(唯一索引)--会访问到不满足条件的第一个值为止
以上这两种情况不做演示
唯一索引:像id这种就是唯一索引,
普通索引:像age等这种可能重复的就是普通索引
3.21总结
间隙锁锁定的是一个范围,但不包含记录本身。当事务持有间隙锁时,其他事务无法在这个间隙中插入新记录。它的主要目的是防止幻读,即避免在当前事务执行过程中,其他事务插入新记录导致当前事务再次查询时出现新的结果。
临键锁是间隙锁和记录锁(Record Lock,锁定单个记录)的组合。它不仅锁定记录本身,还锁定该记录前面的间隙。临键锁是 InnoDB 存储引擎在可重复读(REPEATABLE READ)隔离级别下默认使用的锁机制,能有效防止幻读和不可重复读问题。
4.总结
1.概述
- 在并发访问时,解决数据访问的一致性,有效性问题
- 全局锁,表级锁,行级锁
2.全局锁
- 对整个数据库实例枷锁,加锁后整个示例就处于只读状态
- 性能较差,数据逻辑备份时使用
3.表级锁
- 操作住整张表,锁定粒度大,发生锁冲突概率高
- 表锁(为了锁住整张表,可以添加读锁和写锁)
- 元数据锁(为了防止DML,DDL语句冲突问题)
- 意向锁(为了规避行锁和表锁加锁时冲突问题,避免添加表锁去逐行检查这张表的行锁情况,意向锁不用手动去加)
4.行级锁
- 操作锁住对应的行数据,锁定粒度最小,发生锁冲突的概率最低
- 行锁(共享锁和共享锁兼容,排它锁和排它锁互斥)
- 间隙锁(锁住两条记录之间的间隙,为了避免多个事务并发操作的幻读现象)
- 临建锁(行锁和间隙锁的组合)
- 意向共享锁:它属于表级锁。这意味着意向共享锁是加在整个表上的,用于表明事务后续对表中的行或页有添加共享锁的意图。例如,在 MySQL 的 InnoDB 存储引擎里,当一个事务打算对表内某些行加共享锁时,会先在表级别添加意向共享锁。
- 共享锁:属于行级锁或者页级锁。共享锁可以直接加在具体的数据行或者数据页上,用于控制对这些具体数据资源的并发访问。