签到成功

知道了

CNDBA社区CNDBA社区

MySQL FTWRL(flush tables with read lock) 说明

2021-08-22 21:52 3561 0 转载 MySQL
作者: dave

1 FTWRL 概述

FTWRL(flush tables with read lock)命令主要被备份工具使用,使用逻辑方式进行备份(mydumper,mysqldump)或物理方式进行备份(percona-xtrabackup),为了保证数据的一致性,这两种备份方式都会在备份过程中执行 flush table with read lock 这个命令,通过执行FTWRL,来对事务和非事务表来加table level级别的共享锁,取得此时的gtid或者binlog偏移量,继而得到某一个时间点的一致性备份数据(数据与binlog位点匹配)。

由于FTWRL总共需要持有两把全局的MDL锁,并且还需要关闭所有表对象,因此这个命令的杀伤性很大,执行命令时容易导致库hang住。http://www.cndba.cn/cndba/dave/article/4681

如果是主库,则业务无法正常访问;如果是备库,则会导致SQL线程卡住,主备延迟。http://www.cndba.cn/cndba/dave/article/4681

FTWRL主要包括3个步骤:

http://www.cndba.cn/cndba/dave/article/4681

  1. 上全局读锁(lock_global_read_lock)
  2. 清理表缓存(close_cached_tables)
  3. 上全局COMMIT锁(make_global_read_lock_block_commit)

上全局读锁会导致所有更新操作都会被堵塞;关闭表过程中,如果有大查询导致关闭表等待,那么所有访问这个表的查询和更新都需要等待;上全局COMMIT锁时,会堵塞活跃事务提交。

关闭表导致业务库堵住的典型场景:
假设有3个会话,会话A执行大查询,访问t表;然后一个备份会话B正处于关闭表阶段,需要关闭表t;随后会话C也请求访问t表。三个会话按照这个顺序执行,我们会发现备份会话B和会话C访问t表的线程都处于“waiting for table flush”状态。这就是关闭表引起的,这个问题很严重,因为此时普通的select查询也被堵住了。http://www.cndba.cn/cndba/dave/article/4681http://www.cndba.cn/cndba/dave/article/4681

2 FTWRL与备份

Mysql的备份方式,主要包括两类:逻辑备份 和 物理备份。逻辑备份的典型代表是mysqldump,物理备份的典型代表是extrabackup。

根据备份是否需要停止服务,可以将备份分为冷备热备
冷备要求服务器关闭,这个在生产环境中基本不现实,而且也与FTWRL无关。
Mysql的架构支持插件式存储引擎,通常我们以是否支持事务划分,典型的代表就是myisam和innodb,这两个存储引擎分别是早期和现在mysql表的默认存储引擎。http://www.cndba.cn/cndba/dave/article/4681

对于innodb存储引擎而言,在使用mysqldump获取一致性备份时,我们经常会使用两个参数,—single-transaction和—master-data,前者保证innodb表的数据一致性,后者保证获取与数据备份匹配的一致性位点,主要用于搭建复制。现在使用mysql主备集群基本是标配,所以也是必需的。对于myisam,就需要通过—lock-all-tables参数和—master-data来达到同样的目的。

FTWRL的执行逻辑可以分为下面的几个步骤:

http://www.cndba.cn/cndba/dave/article/4681

  1. 上全局读锁
  2. 清理表缓存
  3. 上全局COMMIT锁

第一步的作用是堵塞更新,备份时,我们期望获取此时数据库的一致状态,不希望有更多的更新操作进来。对于innodb引擎而言,其自身的MVCC机制,可以保证读到老版本数据,因此第一步对它使多余的。

第二步,清理表缓存,这个操作对于myisam有意义,关闭myisam表时,会强制要求表的缓存落盘,这对于物理备份myisam表是有意义的,因为物理备份是直接拷贝物理文件。对于innodb表,则无需这样,因为innodb有自己的redolog,只要记录当时LSN,然后备份LSN以后的redolog即可。

第三步,主要是保证能获取一致性的binlog位点,这点对于myisam和innodb作用是一样的。

所以总的来说,FTWRL对于innodb引擎而言,最重要的是获取一致性位点,前面两个步骤是可有可无的,因此如果业务表全部是innodb表,这把大锁从原理上来讲是可以拆的,而且percona公司也确实做了这样的事情。此外,官方版本的5.5和5.6对于mysqldump做了一个优化,主要改动是,5.5备份一个表,锁一个表,备份下一个表时,再上锁一个表,已经备份完的表锁不释放,这样持续进行,直到备份完成才统一释放锁。5.6则是备份完一个表,就释放一个锁,实现主要是通过innodb的保存点机制。http://www.cndba.cn/cndba/dave/article/4681

3 比FTWRL更好的方法

FTWRL是一种非常重量级锁,或者说采取了一些额外过度的动作。有非常大的可能失败,比如非常大的事务正在执行,这时候会被阻塞;而阻塞的时候又会影响其他的DML事务的执行,这时候是很危险的。http://www.cndba.cn/cndba/dave/article/4681

percona公司提供了改良的方案,在 5.6.16-64.0这个版本中,percona开始引入了两个新的MDL类型的锁,相应的引入了两个新的备份命令:

  1. LOCK TABLES FOR BACKUP
  2. LOCK BINLOG FOR BACKUP

lock tables for backup:
  执行该命令后,获得的新的MDL锁会阻塞对非事务表的更新及所有DDL动作,此时其他用户可以继续更新inonodb引擎的表,但是无法对myisam表进行更新动作。

lock binglog for backup:
  执行该命令后,如果加锁成功,将会阻塞binglog的更新,此时所有的DML操作被阻塞。

两种方式对比如下: 

http://www.cndba.cn/cndba/dave/article/4681

  1. 使用FTWTRL备份的方式,如果myisam表数量众多,或者当前有大事务在执行,FTWTRL处于等待或者FTWTRL保持,这个时间段期间,后续对innod的DML都将被阻塞,因此时间持续越长,对业务影响越大。
  2. 使用 lock tables for backup备份myisam表期间,对innodb的dml事务无影响,且加锁过程不受当前是否有大事务正在执行的影响

使用 lock table和lock binlog来备份数据,不仅可以实现更轻量级的上锁,并且可以节约myisam备份期间对业务的写操作影响,在percona server的环境下,xtrabackup不再使用FTWRL命令了。

用户评论
* 以下用户言论只代表其个人观点,不代表CNDBA社区的观点或立场
dave

dave

关注

人的一生应该是这样度过的:当他回首往事的时候,他不会因为虚度年华而悔恨,也不会因为碌碌无为而羞耻;这样,在临死的时候,他就能够说:“我的整个生命和全部精力,都已经献给世界上最壮丽的事业....."

  • 2296
    原创
  • 3
    翻译
  • 582
    转载
  • 198
    评论
  • 访问:8504465次
  • 积分:4477
  • 等级:核心会员
  • 排名:第1名
精华文章
    最新问题
    查看更多+
    热门文章
      热门用户
      推荐用户
        Copyright © 2016 All Rights Reserved. Powered by CNDBA · 皖ICP备2022006297号-1·

        QQ交流群

        注册联系QQ