Mysql 的锁

136 阅读3分钟

一、锁的分类

mysql锁

按模式分类
    乐观锁
    悲观锁
    
按粒度分类
    全局锁
    表锁
    页面锁
    行锁
    
按属性分类
    共享锁
    排他锁
    
按状态分类
    意向共享锁
    意向排他锁
    
按算法分类
    记录锁
    间隙锁
    临键锁

一、乐观锁和悲观锁

乐观锁和悲观锁不是具体的某种锁,它是锁的一种设计思想。

乐观锁

乐观锁其实并没有锁,它假设数据不会发生冲突,在这个基础上,通过csa算法来是实现多线程并发下的数据同步需求。

悲观锁

悲观锁则相反,认为数据会发生冲突,所以在获取到数据时,会加锁,禁止其他线程修改数据。

排他锁就是一种悲观锁。

二、全局锁、表锁、页面锁、行锁

全局锁

对整个数据库进行加锁,禁止一切修改,包括数据更新以及对表结构的修改。

主要应用于全库逻辑备份操作(mysqldump)。

Flush tables with read lock

表锁

对单个表进行加锁,myisam和innodb都支持表锁。

表级锁又分为 表锁 和 元数据锁。

表锁:写锁互斥、读写互斥、读读兼容。

元数据锁:MDL,分为写锁和读锁。

写锁会禁止ddl操作(修改表结构)和dml操作(修改表数据)。读锁会禁止ddl操作(修改表结构)。

读锁之间不冲突,写锁之间、写锁和读锁冲突。

修改表结构时,禁止对表数据进行查询修改;查询和修改表数据时,禁止对表结构进行修改。

页面锁

BDB数据库支持页面锁,锁定粒度介于行锁和表锁之间,并发度亦然,属于一种比较中庸的锁。

行锁

对单条记录进行加锁,并发度最高,锁冲突少,但容易出现死锁情况。

加锁与释放锁的开销相对来说过大。

三、共享锁和排他锁

共享锁

又称读锁,S锁,多个事务可以共享一把锁。 共享锁与排他锁冲突。

排他锁

又称写锁,X锁,独占锁,不能多个事务同时持有。一个事务获取到排他锁之后,其他事务不能对该数据添加任何锁。

四、意向共享锁和意向排他锁

意向共享锁和意向排他锁是共享锁和排他锁的一个标识。

在表级别上加意向锁,用于加锁前的判断,因为共享锁和排他锁是行级别的锁,判断起来需要循环所有行,资源消耗大。

不需要主动上意向锁,在进行行级加锁时,会自动加上对应的表级意向锁。

五、记录锁、间隙锁和临键锁

记录锁是单行的锁。

间隙锁是两个记录之间的间隙上的锁。

临键锁则是记录锁+间隙锁,由一条记录上的锁和其左侧的间隙锁组合而成。

间隙锁和临键锁只有在RR隔离模式下存在,主要作用是为了解决幻读问题。