一、全局锁
用作全量备份时,保证表与表之间的数据一致性
flush tables with read lock;
使用全局读锁锁定所有数据库的所有表。这时会阻塞其它所有 DML 以及 DDL 操作,这样可以避免备份过程中的数据不一致。接下来可以执行备份,最后用 unlock tables 来解锁
但这属于比较重的操作,可以使用 --single-transaction 参数来完成不加锁的一致性备份(仅针对 InnoDB 引擎的表)
客户端1备份账户表,余额200,客户端2再次期间进行了购买课程,账户课程数为1,客户端备份课程表的时候,读到课程数为1,余额的备份还是之前的200,导致出错。我们可以通过全局锁的方式,解决这个问题
加了一个全局锁
写更新操作会被阻塞
二、表级锁(InnoDB)
1.表锁
语法:加锁 lock tables 表名 read(共享)/write(排它锁),解锁 unlock tables
缺点:粒度较粗,在 InnoDB 引擎很少使用
共享锁能读不能写
排它锁不能读写
2.元数据锁,即 metadata-lock(MDL),主要是为了避免 DML(增删改查) 与 DDL(建删改表) 冲突
加元数据锁的几种情况
lock tables read/write,类型为 SHARED_READ_ONLY 和 SHARED_NO_READ_WRITE
alter table,类型为 EXCLUSIVE,与其它 MDL 都互斥
select,select … lock in share mode,类型为 SHARED_READ
insert,update,delete,select for update,类型为 SHARED_WRITE
DML 的元数据锁之间不互斥
select object_type,object_schema,object_name,lock_type,lock_duration from performance_schema.metadata_locks;(可以查看元数据锁信息)
一个客户端开启事务,查询,其他客户端修改表结构会被阻塞,它保证同一事务内,表结构一样
先执行查锁,再select语句,然后再查看,就可以看到t表上有一个元数据锁,类型为SHARE_READ共享读锁,可以存在多个锁不互斥,持续时间是这个事务当中。
3、IS(意向共享) 与 IX(意向排他),主要是避免 DML 与表锁冲突
DML 主要目的是加行锁,为了让表锁不用检查每行数据是否加锁,加意向锁(表级)来减少表锁的判断,意向锁之间不会互斥
由 DML 语句添加,例如 select … lock in share mode 会加 IS 锁,insert,update,delete, select … for update 会加 IX 锁
select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_locks;(查看意向锁信息)
意向排它锁
意向排它锁决定其他表级共享锁和表级排它锁不能在加
意向共享锁
其他的共享表锁是可以加的
三、行级锁(InnoDB)
种类
1.行锁 – 在 RC 下,锁住的是行,防止其他事务对此行 update 或 delete,
2.间隙锁 – 在 RR 下,锁住的是间隙,防止其他事务在这个间隙 insert 产生幻读
3.临键锁 – 在 RR 下,锁住的是前面间隙+行,特定条件下可优化为行锁
注意
它们锁定的其实都是索引上的行与间隙,根据索引的有序性来确定间隙
间隙锁:
begin;
select * from t where id = 9 for update;//把锁价格8-12间隙,不包括8和12
select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_locks where object_name='t';
可以看出是一个间隙排它锁
临键锁:
临键锁=间隙锁+行锁
begin;
select * from t where id >= 8 for update;
select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_locks where object_name='t';