锁的分类

共享锁/独占锁

锁的粒度

全局锁、表级锁、行锁、页级锁、记录锁、间隙锁、临键锁

锁的状态分类

意向共享锁、意向排他锁

一、全局锁

全局锁就是对整个数据库实例加锁。
MySQL提供了一个加全局读锁的方法,命令是 Flush tables with read lock

二、表级锁

MySQL里面表级别的锁有两种:一种是表锁,一种是元数据锁(meta data lock,MDL)
表锁: lock tables t1 read,t2 wirte;
锁了t1表为read之后,其他线程写t1都被阻塞。 锁了t2表位write之后,其他线程读写t2都将被阻塞。而当前线程只能读t1,读写t2。

元数据锁:
当对一个表做增删改查操作的时候,加MDL读锁;当要对表做结构变更操作的时候,加MDL写锁,也就是同一时间只允许一个事务对表结构变更。

  • 读锁之间不互斥,因此可以有多个线程同时对一张表增删改查
  • 读写锁之间、写锁之间是互斥的,用来保证变更表结构操作的安全性。因此,如果有两个线程要同时给一个表加字段,其中一个要等另一个执行完才能开始执行

三、行锁

也就是说事务A和B都想更新一条记录, 那么就必须一个事务等待另一个事务提交之后才能修改。

  1. 共享锁(S): SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE
  2. 排他锁(X): SELECT * FROM table_name WHERE ... FOR UPDATE

delete 、update 、select… for update 都会加共享锁, 在事务没有结束之前,其他共享锁和排他锁都会阻塞。
事务加了排他锁之后,其他排他锁都会阻塞, 共享锁不会阻塞。

另外,所有的加锁都是当前读,都不走mvcc机制。 在加锁的时候,不影响普通读操作。