欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

一不小心走光了,和浩宸聊一聊数据库的锁。

程序员文章站 2024-03-16 23:26:58
...

一不小心走光了,和浩宸聊一聊数据库的锁。

引入背景

周六,浩宸在卫生间洗澡,然后我没注意,一下推门进去了,浩宸这样走光了,场面顿时尴尬。原来是锁坏了。这时候就提现了锁的重要性。

为什么要引入锁

在日常生活中,我们会共享卫生间,关门上锁可以保护我们的隐私。在数据库中锁同样是为并发所设计的。使用锁可以保证线程的安全性。

锁的分类

锁按粒度可以分为
! 全局锁
!! 表锁 , 元数据锁(meta data lock)
!!! 行锁

全局锁

全局锁从字面上看 就是锁库的锁。加上这把锁之后所有写的操作都将不能执行(增删改的操作,创建表和修改表结构的操作,提交事务的操作)

语法:flush table with read lock 

使用场景:整库备份逻辑备份 。就是把整库的每个表都select出来存成文本。

一不小心走光了,和浩宸聊一聊数据库的锁。
让整库只读,岂不是很危险。
这里具体来描述一下
如果在主库上备份,那么在备份期间不能进行写的操作,整个业务将会停摆。
如果在从库上备份,那么在备份期间从库不能执行主库同步过来的binlog 会导致主从延迟。
一不小心走光了,和浩宸聊一聊数据库的锁。
为什么备份要加锁呢?
那是因为如果不加锁 备份系统备份的库不是一个逻辑时间点,视图不一致。
如何进行备份?
官方自带的逻辑备份工具mysqldump 当mysql使用参数single-transaction到数据之前会启动一个事务,来确保拿到一致性视图,由于mvcc的支持,备份的过程中,数据是可以正常更新的。
有了这个功能为什要引入ftwrl呢?
这就和数据库的存储引擎有关系了。对于MyISAM这种不支持事务的引擎,如果备份过程中有更新,总是 只能取到最新的数据,那么就破坏了备份的一致性。这时,我们就需要使用FTWRL命令了。所以,single-trasaction方法适用于所有表使用事务引擎的库。如果有的表使用了不 支持事务的引擎,那么备份就只能通过FTWRL方法。

说到这里浩宸就提出疑问了,既然是全局可读。为什么不用set globle readonly=true.
1)在有些系统中,readonly的值会被用来做其他逻辑,比如用来判断一个库是主库还是备 库。因此,修改global变量的方式影响面更大,不建议使用
2)在异常处理机制上有差异。如果执行FTWRL命令之后由于客户端发生异常断开,那么 MySQL会自动释放这个全局锁,整个库回到可以正常更新的状态。而将整个库设置为 readonly之后,如果客户端发生异常,则数据库就会一直保持readonly状态,这样会导致整个 库长时间处于不可写状态,风险较高。

表锁,元数据锁(meta data lock)

表锁的语法:lock tables …read/write
lock tables语法除了会限制别的线程的读写 外,也限定了本线程接下来的操作对象。
MDL不需要显式使用,在访问一个表的时候会被 自动加上。MDL的作用是,保证读写的正确性。
在MySQL 5.5版本中引入了MDL,当对一个表做增删改查操作的时候,加MDL读锁;当 要对表做结构变更操作的时候,加MDL写锁。
! 读锁之间不互斥,因此你可以有多个线程同时对一张表增删改查。
!! 读写锁之间、写锁之间是互斥的,用来保证变更表结构操作的安全性。因此,如果有两个线 程要同时给一个表加字段,其中一个要等另一个执行完才能开始执行。

相关标签: MYSQL