本博客日IP超过2000,PV 3000 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog2,之前的微信号好友位已满,备注:返现
受密码保护的文章请关注“业余草”公众号,回复关键字“0”获得密码
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
腾讯云】1核2G5M轻量应用服务器50元首年,高性价比,助您轻松上云
这是一把好锁,真香!
MySQL 全局锁,听到的人可能真没多少。一方面是一些人认为 DBA 才需要深入吧,另一方面多数人接触不到这么深的知识。还有一方面可能就真如大家所说的“没有时间学习”!
昨天那篇文章,我提到了一个数据迁移。我们来看一个场景,现在我为了缩小因删除等造成的 MySQL 占用空间居高不下,我需要进行数据迁移。但是在数据迁移之间,如果还有数据被写入数据库了。如何保证我迁移的就是全量数据,一条也不少呢?
因为我一边读,一边有数据写入。比如一个表,我已经复制完了,你又新增数据了怎么搞?这时最简单的办法就是使用全局锁。
全局锁你也可以理解为数据库级别的锁。也就是锁,这把锁会加给整个数据库。对于上面的场景,我们其实是可以加了全局读锁。一条命令就搞定。
Flush tables with read lock;
Flush tables with read lock 也被简称为 FTWRL。执行这个语句,它会让整个库被处于只读状态。之后的增删改语句就会被阻塞,包括事务的提交,表结构的修改与创建等。
处于只读状态的数据库,我们就可以尽情的去复制了。因为这时你复制的就是整个库,全量数据。所以这把锁一夫当关万夫莫开,真香。
别以为,这把锁力度太大,没什么卵用。其实真实开发工作中,有时候它能帮你解决掉不少麻烦。正所谓存在即合理!
FTWRL 这个命令主要用于备份工具获取一致性备份(数据与binlog位点匹配)。由于 FTWRL 总共需要持有两把全局的 MDL 锁(后面写文章讲),并且还需要关闭所有表对象,因此这个命令的杀伤性很大,执行命令时容易导致库 hang 住。如果是主库,则业务无法正常访问;如果是备库,则会导致 SQL 线程卡住,主备延迟。
数据的一致性有多重要,我就不多说了。最常见的就是你在遍历一个 Java 集合时,可能会出现 ConcurrentModificationException 问题。也就是并发修改异常。这个知识点,我下篇文章来写。这里原谅我先预告一下!
FTWRL 这么牛,背后到底做了哪些事情?它主要干 3 件事。
- 上全局读锁(lock_global_read_lock);
- 清理表缓存(close_cached_tables);
- 上全局COMMIT锁(make_global_read_lock_block_commit)。
上全局读锁会导致所有更新操作都会被堵塞;关闭表过程中,如果有大查询导致关闭表等待,那么所有访问这个表的查询和更新都需要等待;清理表缓存也就是每个表在内存中都有一个 table_cache,不同表的 cache 对象通过 hash 链表维护,刷新它自己的 data,同时也刷新操作系统的 data 到 disk 上;上全局 COMMIT 锁时,会堵塞活跃事务提交。
上全局读锁和上全局 COMMIT 锁都是通过 MDL 锁实现的。这个 MDL 锁 MySQL 底层用到的比较多。后面有文章来重点写。除了本文介绍的锁,MySQL 还有表锁,行级锁等各种锁,我后面会抽时间来一一书写,感兴趣的可以长期的关注!
最后在说一点,当我们执行这个语句后,如何释放锁呢?也就是取消这个锁。也很简单,下面的一条语句即可搞定。
unlock tables
以上,希望能够帮助到大家!
最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加作者微信号:xttblog2。备注:“1”,添加博主微信拉你进微信群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作也可添加作者微信进行联系!
本文原文出处:业余草: » 一夫当关万夫莫开,MySQL全局锁(FTWRL)真香