这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战mysql
MySQL 全局锁会申请一个全局的读锁,对整个库加锁。程序员
全局锁的通常使用场景是:全局逻辑备份。sql
全局锁的实现方式有两种:数据库
//第一种方法
flush tables with read lock(FTWRL)
//第二种方法
set global readonly=true
复制代码
当数据库处于全局锁的状态时,其余线程的一下语句会被阻塞:数据更新语句(数据的增删改)、数据定义语句(建表、索引变动、修改表结构等)和更新类事务的提交语句。markdown
释放全局锁架构
unlock tables;
复制代码
建立数据库 `test`工具
CREATE TABLE `test` (
`name` varchar(32) NOT NULL DEFAULT '',
`bid` int(10) unsigned NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='测试';
复制代码
插入数据:oop
insert into test values('A', 1), ('B',2),('C',3);
复制代码
查看表数据post
> select * from test;
+------+-----+
| name | bid |
+------+-----+
| A | 1 |
| B | 2 |
| C | 3 |
+------+-----+
复制代码
加锁学习
flush tables with read lock;
复制代码
新增数据
insert into test values('D', 4);
复制代码
执行 insert 操做后,直接返回错误结果:
ERROR 1223 (HY000): Can't execute the query because you have a conflicting read lock
复制代码
执行查询操做,能够正常返回结果:
> select * from test;
#返回结果:
+------+-----+
| name | bid |
+------+-----+
| A | 1 |
| B | 2 |
| C | 3 |
+------+-----+
复制代码
能够看到,当咱们加上全局锁的时候,数据及表更新操做都没办法执行,但表查询不受影响。这样会给咱们的业务形成很大的影响(没法修改数据),索性 Innodb 引擎的可重复读隔离级别可让咱们不阻塞数据变动的同时导出数据。
官方自带的逻辑备份工具是 mysqldump。当 mysqldump 使用参数–single-transaction 的时候,导数据以前就会启动一个事务,来确保拿到一致性视图。而因为 MVCC 的支持,这个过程当中数据是能够正常更新的。
你必定在疑惑,有了这个功能,为何还须要 FTWRL 呢?
一致性读是好,但前提是引擎要支持这个隔离级别。
好比,对于 MyISAM 这种不支持事务的引擎,若是备份过程当中有更新,老是只能取到最新的数据,那么就破坏了备份的一致性。这时,咱们就须要使用 FTWRL 命令了。
single-transaction 方法只适用于全部的表使用事务引擎的库。
若是有的表使用了不支持事务的引擎,那么备份就只能经过 FTWRL 方法。这每每是 DBA 要求业务开发人员使用 InnoDB 替代 MyISAM 的缘由之一。
在有些系统中,readonly 的值会被用来作其余逻辑,好比用来判断一个库是主库仍是备库。所以,修改 global 变量的方式影响面更大,我不建议你使用。
在异常处理机制上有差别。若是执行 FTWRL 命令以后因为客户端发生异常断开,那么 MySQL 会自动释放这个全局锁,整个库回到能够正常更新的状态。而将整个库设置为 readonly 以后,若是客户端发生异常,则数据库就会一直保持 readonly 状态,这样会致使整个库长时间处于不可写状态,风险较高。
做者:架构精进之路,十年研发风雨路,大厂架构师,CSDN 博客专家,专一架构技术沉淀学习及分享,职业与认知升级,坚持分享接地气儿的干货文章,期待与你一块儿成长
关注并私信我回复“01”,送你一份程序员成长进阶大礼包,欢迎勾搭。
🎉 文章首发于我的公众号「架构精进之路」,原文连接:用实例带你了解 MySQL 全局锁
Thanks for reading!