全局锁和表级锁(给表加字段的安全做法)
1.根据加锁范围,mysql的锁大致分为 全局锁,表锁和行锁三大类。
2.全局锁
全局锁就是对整个数据库实例加锁。mysql有个加全局锁的命令:Flush tables with read lock,即有名的FTWRL。当需要整个库都处于只读状态时,可以用这个命令。使用这个命令后,其他线程的这些语句会被阻塞:dml(包括数据的增删改),ddl(包括建表,修改表结构等),更新类事务的提交语句。
全局锁的使用场景:
做全库的逻辑备份(mysqldump工具)。即把整库每个表都select出来存成文本。
全局锁的风险:(整个数据库处于只读):
a.如果在主库上备份,则备份期间不能执行更新,业务基本上得停止。
b.如果在从库上备份,则备份期间从库不能执行主库同步过来的binlog,会导致主从延迟。
全局锁的优点:
如果不加全局锁做备份,则备份系统通过备份得到的不是一个逻辑时间点,这个视图是不一致的。
官方的逻辑备份工具mysqldump使用参数 -single-transaction,会在导数据之前开启一个事务,来确保拿到一致性视图。
一致性读是可以解决视图不一致的问题,但前提是引擎要支持这个隔离级别(RR)。像MyIsam这种不支持事务的引擎,如果备份过程中有更新,那也总能获取到最新数据,就破坏了备份的一致性,这种情况下,就只能使用FTWRL命令了。
通过set global readonly=true,也能做到全库只读,但是还是建议使用FTWRL,原因如下:
a.在有些系统中,readonly的值会被用来做其他逻辑,比如判断一个库是主还是备,即修改global变量的方式影响面太大了,不建议使用
b.在异常处理机制上有区别。如果FTWRL命令后 客户端发生异常断开,那么mysql会自动释放这个全局锁,整个库可以回到正常状态;但如果将整个库设置readonly后,如果客户端发生异常,数据库会一直保持readonly状态,整库会长期处于不可写状态。
注:FTWRL 可以用unlock tables主动释放锁
一旦一个库被加上全局锁后,对里面任何表加字段