MySQL中的锁
2019-07-24 09:04:59来源:博客园 阅读 ()
我学习MySQL是半路出家,刚开始接触的时候,只知道数据库的增删改查和事务,直到有一天数据库突然爆出(1205, 'Lock wait timeout exceeded; try restarting transaction'),那时候,我才知道数据库还有锁这么一个玩意。这篇文章简单谈谈我对MySQL锁的理解与总结
一、锁的设计是为了解决什么问题?
我们知道数据库能够支持多用户共同读写,当多用户读写数据的时候,就有可能会出现同一时刻对多个用户对同一条数据的读写,就会出现下面的场景:
- 大家都只是对这一条数据进行读取
- 有一部分人想要对这一条数据进行读取,有一部分人想要对这一条数据进行修改
- 大家都想要对这一条数据进行修改
对于场景1,数据不会变化,大家读到数据都是一样的,
对于场景2,若读数据的人不关心修改后的数据,只关心当前的值,对于读数据的人是没有影响的,对于修改数据的人,问题就出现了,大家都拿去修改了,然后保存了自己修改的值,这样的话,我们要以谁修改的值为准呢,或者后面保存修改值的人会把前面保存的结果给覆盖掉。
对于场景3,写数据会出现和场景2一样的情况。
如何优雅的解决上面的问题呢?数据库引入了锁的概念,数据可以加锁,用来控制对数据的合理访问。对于上面的场景3,当用户1想要修改这一条数据时,必须先获取这一条数据的锁,然后在修改,同时用户2想要修改这一条数据时,也要先获取这一条数据的锁,但锁被用户1获取了,他只能等用户1修改完,释放锁后,才能继续修改这一条数据,这样每个人都能修改数据,就不会乱了。
根据锁的类型可以分为读锁,写锁
根据锁的范围可以分为全局锁,表级锁,行锁
二、读锁,写锁
当我们需要对一个数据进行读取的时候,就需要获取读锁,当我们对一个数据进行修改的时候,就需要获取写锁
读锁之间不互斥,当对一个数据加了读锁后,还可以对它继续加读锁,不能添加写锁
写锁与读锁之间,写锁与写锁之间互斥,当对一个数据加了写锁后,不能继续添加其他锁了,必须要等待写锁释放
三、全局锁
全局锁,会锁住整个数据库,整个数据库不可写入数据,不可修改数据表结构,只能读取数据,这样的话,就保证了整个数据库只读,最典型的应用就是全局备份数据,备份数据期间,我们不希望有数据能写入数据库中,不然后有可能备份后的数据是不完整的数据。
比如有两个表中的数据是关联的,第一张表a,第二张表b,表a增加一条记录时,表b就会记录一条关于表a操作的记录
现在在我们备份的时候,不加全局锁,考虑下面的情况
时刻1. 备份表a
时刻2. 表a插入了一条记录,表b也要记录一条
时刻3. 备份表b
这样的顺序下来,备份后的数据表b中多记录了一次操作
我们可以通过加全局锁,来实现在备份过程中,只能读取数据,无法修改数据,来保证备份后数据的一致性
四、表级锁
表级锁可分为两种,一种是表锁,一种元数据锁(MDL)
MDL锁不需要显示使用,在访问表的时候会自动加上
当要读取一个表时,要获取MDL读锁,当要修改一个表的结构的时候,就要获取MDL写锁。MDL主要是为了防止DDL和DML并发的冲突。
表锁锁一整表,锁的范围还是太大了。
五、行锁
行锁时目前最细粒度的锁了,只有Innodb引擎支持,MYISAM引擎只支持到表级锁
innodb事务开启后,行锁是需要的时候才会加上,但不是不需要了就会立即释放行锁,而是等整个事务提交之后,才会释放行锁。这个就是mysql的两阶段锁协议。
有这么一种场景,一个事务执行中,要执行很多条语句,其中有一条语句会更新同一行数据。当多个事务并发的时候,必定会争夺同一行数据的锁,当一个事务持有锁的时候,其他事务就必须等待。在这种场景下,我们该如何设计语句的执行顺序,让等待的时间最少?
我们已经知道了两阶段锁协议,锁在事务结束的时候才会释放,所以,把更新同一行数据的语句越往后放,等待的时间就会越少。
innodb已经有了行锁,但还是不能够保证并发事务的正确性,为此,innodb引入了新的锁,叫间隙锁,当要更新数据时,在一行行扫描加锁的过程中,不仅会加行锁,还会添加间隙锁,也就数据行之间的锁。
六、总结
MySQL中的锁机制就是为了解决共享资源的问题,为了从不同程度控制资源的读写,相应的引入了全局锁,表级锁,行锁,以及不同锁类型。
原文链接:https://www.cnblogs.com/time-read/p/11227107.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:MySQL数据库的特点和优势
下一篇:一分钟安装mysql
- MySQL replace函数怎么替换字符串语句 2020-03-09
- PHP访问MySQL查询超时怎么办 2020-03-09
- mysql登录时闪退 2020-02-27
- MySQL出现1067错误号 2020-02-27
- mysql7.x如何单独安装mysql 2020-02-27
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash