06 | 全局锁和表锁 :给表加个字段怎么有这么多阻碍?
Page content
06 | 全局锁和表锁 :给表加个字段怎么有这么多阻碍?

mysql锁分类
- 全局锁
- 表级锁
- 行锁
如何加全局锁
MySQL加全局读锁:Flush tables with read lock (FTWRL)
全局锁的使用场景是什么
全库逻辑备份
通过加全局锁备份数据库会导致什么问题
- 在主库上加全局锁,加锁期间整库都不能更新,业务几乎停摆
- 在从库上加全局锁,加锁期间不能执行主库同步过来的binlog,导致主从延迟
备份数据为什么要加锁
为了数据的一致性
通过一致性读来备份数据库
在可重复读隔离级别下,开启一个事务,就可以拿到一个一致性读视图,由于MVCC的支持,备份期间数据库是可以正常更新的
既然可以用一致性读视图来备份数据库为什么还需要FTWRL
一致性读并不是每个数据库引擎都支持的,要想使用这种方式备份方式,要求数据库里每张表使用的都是支持事务的引擎
为什么不使用set global readonly=true
- 某些系统中,readonly会被用来做其它逻辑,比如判断一个库是主库还是从库
- 执行 FTWRL 之后,即使客户端异常断开,MySQL也会自动释放这个全局锁;如果执行 set global readonly=true之后客户端异常断开,则正库会一直处于不可写状态
表级锁的分类
- 表锁
- 元数据锁(MDL)
lock tables锁对线程的限制
加锁:lock tables … read/write 解锁:unlock tables … lock tables 除了限制别的线程的读写,也限制来接下来这个线程可以进行的操作
元数据锁MDL
- 无需显示调用,在访问一个表的时候会自动加锁,用于解决或者保证DDL操作与DML操作之间的一致性。
- 对一个表做增删改查操作的时候,加 MDL 读锁;
- 当要对表做结构变更操作的时候,加 MDL 写锁;
如何安全地给小表加字段
在 alter table 语句里设置等待时间,如果在这个时间拿到MDL写锁最好,拿不到就先放弃,以免影响后面的业务,之后再重试执行
问题讨论
备份一般都会在备库上执行,你在用–single-transaction 方法做逻辑备份的过程中,如果主库上的一个小表做了一个 DDL,比如给一个表上加了一列。这时候,从备库上会看到什么现象呢?