MySQL dba在平常工做中,数据备份绝对是工做频度最高的工做内容之一。当你使用逻辑方式进行备份(mydumper,mysqldump)或物理方式进行备份(percona-xtrabackup),为了保证数据的一致性,这两种备份方式都会在备份过程当中执行 flush table with read lock 这个命令(**如下简称为FTWRL**
),经过执行FTWRL,来对事务和非事务表来加table level级别的共享锁,取得此时的gtid或者binlog偏移量,继而获得某一个时间点的备份数据。mysql
在过去的很长一段时间内,咱们作备份一直是按以上的方式来作的,那么这种依靠FTWRL这种方式得到备份点的作法是否真的合理,对数据库有什么不良的影响吗?sql
首先让咱们来看下,FTWRL具体作了哪些事情,当flush tables with read lock这条命令在数据库中被执行的时候,执行逻辑能够分为下面的几个步骤:数据库
步骤1、请求得到相关类型的 MDL lock,这里咱们暂时称之为 FTWRL_MDL_LOCK. 步骤2、清空query cache中的内容(当前应该不多有人开启这个功能了) 步骤3、FLUSH TABLES,将当前全部打开的table的fd关闭 步骤4、请求得到全局table-level lock
步骤5、上全局COMMIT锁(make_global_read_lock_block_commit)
以上步骤,在某些db场景下会产生很是严重的问题,咱们如下面栗子说明:
当有很大的事务在进行的时候,此时FTWRL的步骤一,步骤二能够完成,可是进行到步骤三的时候,因为表相关的事务正在执行中,相应table的句柄被占用,没法进行flush table操做。ide
笔者当时在现网就遇到这种情景,当时使用的工具是mydumper,该工具在进行到FTWRL步骤的时候,在步骤三卡住了,此时工具hang在那里,可是还误觉得加锁失败,天然对业务不会形成影响,实际上步骤一,步骤二已经成功执行了,要命的是步骤一的FTWRL_MDL_LOCK对DML事务的排他的,因此在工具hang住的期间,其余的后续DML事务都是被阻塞的 -_-工具
咱们发现FTWRL是一种很是重量级锁,或者说采起了一些额外过分的动做。有很是大的可能失败,好比很是大的事务正在执行,这时候会被阻塞;而阻塞的时候又会影响其余的DML事务的执行,这时候是很危险的!spa
那是否有改良的更好方案呢,percona的回答的是确定的,在 5.6.16-64.0这个版本中,percona开始引入了两个新的MDL类型的锁,相应的引入了两个新的备份命令code
> LOCK TABLES FOR BACKUP > LOCK BINLOG FOR BACKUP
执行该命令后,得到的新的MDL锁会阻塞对非事务表的更新及全部DDL动做,此时其余用户能够继续更新inonodb引擎的表,可是没法对myisam表进行更新动做。server
执行该命令后,若是加锁成功,将会阻塞binglog的更新,此时全部的DML操做被阻塞。事务
那么经过上面两个命令在获取一致性的数据备份相比以前用FTWRL,有什么好处呢,咱们经过下面两张图能够看到区别:v8
首先咱们看下在非percona-5.6.16-64.0版本中。xtrabackup的工做流程:
而后咱们看下percona-5.6.16-64.0版本及以上中,xtrabackup备份的流程是怎样的:
从上面两张图咱们能够总结以下:
一、使用FTWTRL备份的方式,若是myisam表数量众多,或者当前有大事务在执行,FTWTRL处于等待或者FTWTRL保持,这个时间段期间,后续对innod的DML都将被阻塞,所以时间持续越长,对业务影响越大。
二、使用 lock tables for backup备份myisam表期间,对innodb的dml事务无影响,且加锁过程不受当前是否有大事务正在执行的影响
咱们能够发现使用 lock table和lock binlog来备份数据,不只能够实现更轻量级的上锁,而且能够节约myisam备份期间对业务的写操做影响,我在percona server的环境下试验证了如下,能够看到xtrabackup再也不使用FTWRL命令了
percona这个小的改动解决了以前长期以来热备数据的问题,特别是非percona server 版本下的云平用户有的执着使用myisam引擎,在备份期间很是容易形成监控程序的写入失败,从而触发告警,-_-。