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

Page content

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

20210203091010

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,比如给一个表上加了一列。这时候,从备库上会看到什么现象呢?