【锁机制】MySQL锁机制

1.全局锁

全局锁就是对整个数据库实例加锁,当加全局锁的时候,整个数据库处于只读状态。全局锁的使用场景是给数据库做备份。

2.表级锁

表级锁分为两种:表锁和元数据锁(meta data lock,MDL)。

2.1表锁

表锁的语法是 lock tables … read/write,例如执行下面的语句

lock tables t1 read,t2 write;

表明对表t1加读锁,对表t2加写锁。此时其他线程只能读t1,不能写t1,且不能读写t2。同时当前线程也只能读t1,读写t2,且不能访问其他表。

2.2元数据锁

元数据锁也叫MDL,在访问一个表的时候会被自动加上。当对一个表进行增删改查的时候,加MDL读锁;当队一个表进行结构变更时,加MDL写锁。

需要注意:MDL读锁之间不互斥;读锁和写锁之间、写锁和写锁之间时互斥的

因此,多个线程可以同时对一个表进行增删改查操作,但当线程A对表插入一个字段的时候,其他线程必须等待线程A插入完成后才可以对该表进行其他操作。

3.行锁

行锁顾名思义就是对表中的一行进行加锁,比如事务A更新了一行,此时事务B也想更新同一行,就必须等待事务A释放锁才能更新。

3.1两阶段锁协议

行锁是在需要时才加上的(比如更新一行时),但是不是立即释放,而是等到持有该锁事务提交之后,行锁才会释放。

3.2死锁

举个栗子:首先我们分为四个时间段:

(1)事务A开启,执行语句:update t set k=k+1 where id=1;

(2)事务B开启,执行语句:update t set k=k+1 where id=2;

(3)事务A执行语句:update t set k=k+1 where id=2;

(4)事务B执行语句:update t set k=k+1 where id=1;

前两个时间段内语句执行正常,在第三个时间段时,事务A想要修改id=2这一行的数据,但此时事务A只能等待事务B释放id=2这一行的行锁后才能修改(事务B在第二个时间段时持有,但行锁只有在事务结束时才能释放);

接下来第四个时间段内,事务B想要修改id=1这一行的数据,但此时事务B只能等待事务A释放id=1这一行的行锁才能修改(事务A在第一个时间段时持有,但锁只有在事务结束时才能释放)。

此时两个事务相互等待对方释放行锁,这就是死锁。

3.3死锁检测

死锁检测是解决死锁的有效方法:当MySQL发起死锁检测并发现死锁的时候,会让其中一个事务回滚,进而让其他事务正常进行。

猜你喜欢

转载自blog.csdn.net/m0_52373742/article/details/122799573