锁是计算机协调多个进程或线程并发访问某一资源的机制。保证数据的一致性。
是对数据库中的每张表进行锁定,后续的DDL和DML语句,都会被阻塞住。
场景:
做全库的逻辑备份(保证数据的一致性、完整性)
# 加锁
flush tables with read lock;
# 解锁
unlock tables;
# 备份的语句:
mysqldump -uroot -p密码 数据库名>备份文件名称.sql;
# 注意:该语句不是sql语句,是在命令行模式下执行。
特点:
在表锁中,又分为两个锁:
表共享的读锁:允许多用户读数据,但不允许写数据(包括自己)。
表独享的写锁:允许当前用户读写数据,不允许其他用户读写数据。
# 加锁
lock tables 表名 read/write;
# 解锁
unlock tables/客户端断开
MDL是系统控制的,不需要手动去加锁。
作用:
维护表元数据的一致性,在表上有活动事务的时候,不可以对元数据进行写入操作。
一句话:
避免DML和DDL冲突,保证读写的正确性。(DML:操作表的数据。DDL:表结构相关的操作)
MDL是在Mysql5.5引入的。
读写锁是兼容的,也就是说:我们可以同时存在对表数据的增删改查。
alter修改表结构的时候加的锁是互斥的。也就是:当我们有其他锁存在时候,alter得等到其他锁释放之后,才能加上互斥锁。
注意:
开启事务是不会加上的,当我们在事务中执行相关SQL语句的时候,他才能加上对应的锁。
查看元数据锁:
select object_type,object_schema,object_name,lock_type,lock_duration from performance_schema.metadata_locks;
元数据锁的使用不是仅局限于事务操作内,它可能在任何情况下被 MySQL 系统自动使用以保护关键数据的完整性和一致性。
例如:
使用alter,rename更改表结构的时候,都有可能涉及到元数据锁的使用。
意向锁的前提是有行级锁
为了避免DML在执行时,加的行锁与表锁的冲突,在InnoDB中引入了意向锁,使得表锁不用检查每行数据是否加锁,使用意向锁来减少表锁的检查。
为什么引入意向锁?
当没有意向锁的时候,我们加了行锁之后,想要加表锁,那么就得在加表锁前去全表扫描,看有没有加行锁,要是加了就阻塞。要是没有加行锁,那么表锁就添加成功。
有了意向锁之后,在加了行锁之后,同时也会给表加一个意向锁。当加表锁的时候,就会检查这个表上边有没有意向锁,如果有就检查和我这个表锁兼不兼容,兼容就直接加锁成功,要是不兼容就阻塞。
意向锁的出现,解决了全表扫描检查行锁时,效率低下的问题。
意向锁的分类:
查看意向锁和行锁:
select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_locks;
锁定单个行记录的锁,防止其他事务对此进行 update 和 delete。在RC(读已提交)、RR(可重复读)隔离级别下都支持。
行锁的分类:
针对唯一索引进行检索时,对已存在的记录进行等值匹配时,将会自动优化为行锁(也就说通过过滤条件为唯一索引的字段进行操作的时候,会自动加行级锁)。
InnoDB的行锁是针对于索引加的锁,不通过索引条件检索数据,那么InnoDB将对表中的所有记录加锁,此时就会升级为表锁。
name是没有加索引的。
查询行锁的语句(和意向锁一样):
select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_locks;
锁定索引记录间隙(不含该记录),确保索引记录间隙不变,防止其他事务在这个间隙进行insert,产生幻读。在RR(可重复读)隔离级别下都支持。
注意:
间隙锁唯一目的是防止其他事务插入间隙。间隙锁可以共存,一个事务采用的间隙锁不会阻止另一个事务在同一间隙上采用间隙锁。
行锁和间隙锁组合,同时锁住数据,并锁住数据前面的间隙Gap。在RR隔离级别下支持。
如果文章中有描述不准确或者错误的地方,还望指正。您可以留言或者私信我。
最后希望大家多多 关注+点赞+收藏^_^,你们的鼓励是我不断前进的动力!!!
感谢感谢~~~