全局锁(FTWRL)
让整个数据库处于只读状态,加了全局锁会使得增删改(DML)、表结构的更改(DDL)、更新事务的提交都会阻塞
操作 | 命令 |
---|---|
加锁 | flush table with read lock |
释放锁 | unlock tables |
作用:全局逻辑备份
低效率的原因:
- 如果你在主库上备份,那么备份期间不能执行更新,业务基本上就得停止
- 如果你在从库上备份,那么备份期间从库不能执行主库同步过来的binlog,会导致主从延迟
表锁
顾名思义对表进行上锁操作
操作 | 命令 |
---|---|
加锁 | lock tables read/write |
释放锁 | unlock tables |
加锁方式:自动加锁
优势:开销小,加锁快,无死锁
劣势:锁粒度大,发生锁冲突的概况高,并发处理
MDL元数据锁(metadata lock)
当对一个表进行增删查时加MDL读锁;当对表结构做更改时加DML写锁
- 读锁之间不互斥,所以可以多个线程同时对一张表增删改查改
- 读写锁之间是互斥的,如果有多个线程要同时给一个表加字段,其中要等待另外一个执行完成才能开始执行
两阶段锁协议:在需要的时候才加上的,并不是不需要了就立刻释放,而是要等到事务提交后才会释放
DML锁基于两阶段锁协议
由于DML是自动加锁的,所以当有长事务正在执行时去修改表结构会导致阻塞因此引出正确的修改流程online ddl :
- 拿MDL写锁
- 降级为DML读锁
- 真正做DDL
- 升级成DML写锁
- 释放DML锁
还是可能会出现阻塞大量数据的情况,因为这个online ddl只针对拿到锁后的优化,没拿到锁一样会出现问题
行锁
首先注意InnoDB的行锁是针对索引加的锁,不是针对记录加的锁,并且该索引不能失效,否则都会从行锁升级为表锁
行锁也是基于两阶段锁协议,插入数据就会锁表,更新数据就会锁行
优势:锁粒度小,发生锁冲突的概率低,处理并发能力强
劣势:开销大,加锁慢,会出现死锁
加锁的方式:自动加锁,对于update,delete和insert语句InnoDB会自动给涉及到的数据集加排它锁;对于普通的select语句,InnoDB不会加任何锁,当然我们也可以显示的加锁
记录锁
行锁的衍生,出现条件必须是精准命中索引并且是索引是唯一索引
间隙锁
查询数据用范围查找而不是条件查询,查询条件命中索引并且没有查询到符合条件的记录,此时就会对范围条件中的范围数据进行锁定
遵循左开右闭,比如范围查询的主键为>1&&<5的数据,则间隙锁的是(1,5]
临键锁
查询数据用范围查找,查询条件命中索引且有匹配到数据库记录
比如范围查询(1,8),8没有命中记录则锁住的(1,无穷),如果命中则锁住的(1,8]
结尾
最后引入一个存储引擎:InnoDB和Mylsam的最大不同点
- InnoDB支持事务
- 默认采用行级索,加锁可以保证事务的一致性,所以说有锁的就有事务
以上只是自己学习总结出的一些东西,之后会慢慢补全完善