我,卷王!
共 5248字,需浏览 11分钟
·
2021-08-16 01:43
大家好,我是小林。
全局锁
全局锁是怎么用的?
flush tables with read lock
对数据的增删查改操作,比如 select、insert、delete、update等语句;
对表结构的更改操作,比如 alter table、drop table 等语句。
unlock tables
全局锁应用场景是什么?
先备份了用户表的数据;
然后有用户发起了购买商品的操作;
接着再备份商品表的数据。
加全局锁又会带来什么缺点呢?
既然备份数据库数据的时候,使用全局锁会影响业务,那有什么其他方式可以避免?
–single-transaction
参数的时候,就会在备份数据库之前先开启事务。这种方法只适用于支持「可重复读隔离级别的事务」的存储引擎。表级锁
MySQL 表级锁有哪些?具体怎么用的。
表锁;
元数据锁(MDL);
意向锁;
AUTO-INC 锁;
表锁
//表级别的共享锁,也就是读锁;
lock tables t_student read;
//表级别的独占锁,也就是写锁;
lock tables t_stuent wirte;
unlock tables
元数据锁
对一张表进行 CRUD 操作时,加的是 MDL 读锁;
对一张表做结构变更操作的时候,加的是 MDL 写锁;
MDL 不需要显示调用,那它是在什么时候释放的?
首先,线程 A 先启用了事务(但是一直不提交),然后执行一条 select 语句,此时就先对该表加上 MDL 读锁;
然后,线程 B 也执行了同样的 select 语句,此时并不会阻塞,因为「读读」并不冲突;
接着,线程 C 修改了表字段,此时由于线程 A 的事务并没有提交,也就是 MDL 读锁还在占用着,这时线程 C 就无法申请到 MDL 写锁,就会被阻塞,
为什么线程 C 因为申请不到 MDL 写锁,而导致后续的申请读锁的查询操作也会被阻塞?
意向锁
在使用 InnoDB 引擎的表里对某些记录加上「共享锁」之前,需要先在表级别加上一个「意向共享锁」;
在使用 InnoDB 引擎的表里对某些纪录加上「独占锁」之前,需要先在表级别加上一个「意向独占锁」;
//先在表上加上意向共享锁,然后对读取的记录加独占锁
select ... lock in share mode;
//先表上加上意向独占锁,然后对读取的记录加独占锁
select ... for update;
AUTO-INC 锁
AUTO_INCREMENT
属性时,之后可以在插入数据时,可以不指定该字段的值,数据库会自动给该字段赋值递增的值,这主要是通过 AUTO-INC 锁实现的。AUTO_INCREMENT
修饰的字段赋值递增的值,等插入语句执行完成后,才会把 AUTO-INC 锁释放掉。AUTO_INCREMENT
修饰的字段的值是连续递增的。AUTO_INCREMENT
修饰的字段加上轻量级锁,然后给该字段赋值一个自增的值,就把这个轻量级锁释放了,而不需要等待整个插入语句执行完后才释放锁。当 innodb_autoinc_lock_mode = 0,就采用 AUTO-INC 锁;
当 innodb_autoinc_lock_mode = 2,就采用轻量级锁;
当 innodb_autoinc_lock_mode = 1,这个是默认值,两种锁混着用,如果能够确定插入记录的数量就采用轻量级锁,不确定时就采用 AUTO-INC 锁。
行级锁有哪些?
Record Lock,记录锁,也就是仅仅把一条记录锁上;
Gap Lock,间隙锁,锁定一个范围,但是不包含记录本身;
Next-Key Lock:Record Lock + Gap Lock 的组合,锁定一个范围,并且锁定记录本身。
//对读取的记录加共享锁
select ... lock in share mode;
//对读取的记录加独占锁
select ... for update;