本文转载自微信公众号《架构改进之路》,作者的架构改进之路。转载本文请联系建筑改良之路公众号。MySQL全局锁会申请一个全局读锁,锁住整个库。全局锁一般的使用场景是:全局逻辑备份。全局锁的实现方式有两种://第一种方法是Flushtableswithreadlock(FTWRL)//第二种方法是setglobalreadonly=true当数据库处于全局锁状态时,其他线程后面的语句会被阻塞:数据更新语句(数据的增删改查)、数据定义语句(建表、修改索引、修改表结构等)和更新事务的提交语句。释放全局锁unlocktables;举个例子~创建数据库`test`CREATETABLE`test`(`name`varchar(32)NOTNULLDEFAULT'',`bid`int(10)unsignedNOTNULLDEFAULT'0')ENGINE=InnoDBDEFAULTCHARSET=utf8mb4COMMENT='Test';插入数据insertintotestvalues('A',1),('B',2),('C',3);查看表数据>select*fromtest;+-----+-----+|name|bid|+-----+-----+|A|1||B|2||C|3|+-----+-----+锁定flushtableswithreadlock;添加新数据insertintotestvalues('D',4);执行插入操作后,直接返回错误结果:ERROR1223(HY000):Can'texecutethequerybecauseyouhaveaconflictingreadlock执行查询操作,可以正常返回结果:>select*fromtest;#Return结果:+-----+-----+|名称|出价|+-----+-----+|A|1||B|2||C|3|+------+-----+可以看出,当我们加了全局锁的时候,不能进行数据和表的更新操作,但是不影响表的查询。这会对我们的业务产生很大的影响(数据不可修改),而Innodb引擎的可重复读隔离级别让我们可以在不阻塞数据变化的情况下导出数据。官方自带的逻辑备份工具是mysqldump。当mysqldump使用参数--single-transaction时,会在导入数据之前启动一个事务,以保证视图的一致性。由于MVCC的支持,这个过程中可以正常更新数据。您一定想知道,有了这个功能,为什么还需要FTWRL?一致性读取很好,但前提是引擎支持此隔离级别。比如MyISAM这种不支持事务的引擎,如果在备份过程中有更新,总是只能取到最新的数据,这样会破坏备份的一致性。这时候我们就需要用到FTWRL命令了。单事务方式只适用于所有使用事务引擎库的表。如果有些表使用了不支持事务的引擎,那么备份只能通过FTWRL方式来完成。这通常是DBA要求业务开发人员使用InnoDB而不是MyISAM的原因之一。使用FTWRL代替setglobalreadonly=true在某些系统中,readonly的值会被用于其他逻辑,比如判断一个库是主库还是备库。所以修改全局变量的方式影响比较大,不推荐大家使用。异常处理机制存在差异。如果执行FTWRL命令后客户端异常断开,MySQL会自动释放全局锁,整个库恢复到可以正常更新的状态。整个库设置为readonly后,如果客户端出现异常,数据库会一直处于readonly状态,会导致整个库长期处于不可写状态,风险较大。
