数据库---锁

目录

全局锁

   全局锁的问题

表级锁

表锁

表共享读锁 

表独占写锁 

元数据锁(MDL)

意向锁

行级锁(Innodb存储引擎支持)

行锁

间隙锁 临键锁

​​总结 

悲观锁:

乐观锁:

死锁 

如何避免死锁?


锁是计算机协调多个线程并发执行的机制,事务并发处理时产生的问题,需要借助锁来解决

全局锁

全局锁对整个数据库加锁,这样整个数据库都陷入了“只读”状态,后序任何的更新操作都不能执行

典型的使用场景是对数据库的所有数据库的数据备份(对全部的数据库都会加锁)

增加全局锁:flush tables with read lock

mysql数据库提供了一个数据库备份的工具:mysqldump

mysqldump -uroot 数据库密码 备份数据库名称 > 备份数据库到哪一个sql文件

解锁 unlock tables

全局锁:

全局锁是对全库的锁,即使在一个数据库下建立全局锁,也是锁住了全部的数据库

数据备份:

 会在指定位置创建文件

 解除锁

全局锁的问题

1、如果在主库中备份数据,那么主库所有的更新操作都会阻塞

2、如果在从库中备份数据,那么从库备份期间,不能接受来自主库的二进制日志(binlog),导致主从延迟

(为了防止数据库出现异常,会设置主库和从库。数据库中有一个binlog文件,记录了数据库的所有SQL语句,以二进制文件的形式存储在磁盘当中,从库就是要复制这些SQL语句,将其在从库中执行一遍。如果在从库中备份数据,那么从库陷入只读操作,不能接收来自主库的二进制日志,导致有些SQL语句,从库没有执行,导致从库和主库的信息不对等)

表级锁

锁住某一张表,粒度(锁的作用范围)大,并发性最低,发生锁冲突的概率最高

表锁

加锁:lock tables 表名 read/write

解锁:unlock tables

表共享读锁 

 一旦某一个表增加了读锁,那么这个表无论是当前客户端还是其他客户端,都只能读,不能写

表独占写锁 

 一个客户端对一个表增加了写锁,那么这个客户端可以对这个表进行读和写操作,另外一个客户端对这个表的读和写都是阻塞的

元数据锁(MDL)

MDL是为了保护在并发状态下,元数据和表数据结构的一致性

如果有事务在进行增删改查的操作,保证其他事务不可以修改表结构

如果有事务正在修改表结构,那么不允许其他事务进行增删改查的操作

意向锁

意向锁分为意向共享锁和意向排他锁

意向共享锁:和表级的共享锁兼容,和表级排他锁互斥

意向排他锁:和表级的共享锁,表级排他锁互斥

意向锁之间相互兼容

行级锁(Innodb存储引擎支持)

每一次加锁锁住的是行数据,根据索引列加锁

行锁

两种类型的行锁

共享锁:一个事务获取了这行的共享锁,另外一个事务仍然可以获取这行数据的共享锁

排他锁:一个事务获取了这行的排他锁,另外一个事务不可以获取这行数据的共享锁和排他锁

间隙锁 临键锁

总结 

锁模式悲观锁 乐观锁
锁范围全局锁 表锁 页锁 行锁
锁属性共享锁 排他锁
锁状态意向共享锁 意向排他锁

悲观锁:

            数据库总是认为多个数据库并发操作会发生冲突,所以总是要求加锁操作。悲观锁主要体现为表锁、行锁、页锁。

乐观锁:

  数据库认为多个数据库并发操作不会发生冲突,所以总是不加锁操作。所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。乐观锁的实现方式一般包括使用版本号和时间戳。

 

死锁 

指两个或者两个以上的进程在执行过程中,因为争夺资源而造成的一种互相等待的现象

产生死锁的四个必要条件

1)互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。

2)请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。

3)不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。

4)环路等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。

如何避免死锁?

死锁的四个必要条件:互斥、占有且等待、不可强占用、循环等待。只要系统发生死锁,这些条件必然成立,但是只要破坏任意一个条件就死锁就不会成立。

在数据库层面,有两种策略通过「打破循环等待条件」来解除死锁状态:

  • 设置事务等待锁的超时时间。当一个事务的等待时间超过该值后,就对这个事务进行回滚,于是锁就释放了,另一个事务就可以继续执行了。在 InnoDB 中 innodb_lock_wait_timeout 是用来设置超时时间的,默认值时 50 秒。当发生超时后,就出现下面这个提示:

  • 开启主动死锁检测。主动死锁检测在发现死锁后,主动回滚死锁链条中的某一个事务,让其他事务得以继续执行。将参数 innodb_deadlock_detect 设置为 on,表示开启这个逻辑,默认就开启。当检测到死锁后,就会出现下面这个提示:

注意: 

1、意向锁是InnoDB自动加的,不需用户干预。意向锁不会与行级的共享 / 排他锁互斥

2、排他锁指的是一个事务在一行数据加上排他锁后,其他事务不能再在其上加其他的锁。但可以直接通过select ...from...查询数据,因为普通查询没有任何锁机制

3、mysql InnoDb引擎中update,delete,insert语句自动加排他锁

4、

表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低
行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高   
页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值