摘要:本文来自华为云MySQL研发团队,主要分享了MySQL备份工具Xtrabackup的备份过程、华为云数据库团队对其做的优化改进,以及在使用中可能遇到的问题与解决方法。
本文来自华为云MySQL研发团队,主要分享了MySQL备份工具Xtrabackup的备份过程、华为云数据库团队对其做的优化改进,以及在使用中可能遇到的问题与解决方法。文章讨论的内容主要是针对华为云RDSforMySQL,以及用户自建的社区版MySQL数据库,希望有助于大家理解和使用Xtrabackup,以后面对Xtrabackup问题也更加从容。
一、Xtrabackup简介Xtrabackup是Percona团队开发的用于MySQL数据库物理热备份的开源备份工具,具有备份速度快、支持备份数据压缩、自动校验备份数据、支持流式输出、备份过程中几乎不影响业务等特点,是目前各个云厂商普遍使用的MySQL备份工具。
当前Xtrabackup存在两个版本:Xtrabackup2.4.x与8.0.x,分别用于备份MySQL5.x与MySQL8.0.x版本。下面我们分别介绍Xtrabackup如何备份MySQL社区版以及华为云上的Xtrabackup的备份原理
二、社区版MySQL的Xtrabackup备份Xtrabackup是为PerconaMySQL设计的,同时也支持对官方社区版本MySQL进行备份,过程如下图所示:
兼容性检查:Xtrabackup社区版本只支持MyISAM,InnoDB,CSV,MRG_MYISAM四种存储引擎的表,其他存储引擎的表不会备份;在这一步中,通过查询tables,若发现存在表的存储引擎不是上述四种引擎之一,会打印warning,表明Xtrabackup不会备份该表。
启动redo后台备份线程:启动redo后台备份线程,从备份实例的最近一次checkpointLSN的位置开始备份所有增量的redolog,一直持续到备份任务结束。
加载所有的innodb表空间:打开并扫描所有innodb表的数据文件,检查所有表空间的第一个页面,初始化所有表的内存结构。
备份innodb表:遍历步骤3所构建的表的内存结构,备份每一个innodb表的数据文件,备份的过程中会检查每个页面的数据是否正确。
加备份锁FLUSHTABLESWITHREADLOCK(FTWRL):FTWRL锁是MySQL实例级的读锁,加锁过程复杂,且加锁之后,所有表的所有更新操作以及DDL都会堵塞。
备份非innodb表:因为在步骤5我们已经对实例加了读锁,因此,此时备份非innodb表是安全的,此时一定没有写业务。
记录binlog当前的GTID信息:请注意,此时我们仍持有全局读锁。这一步主要是方便我们使用该备份集快速地创建出备机。
停止redo备份线程。
释放锁资源,备份结束。
需要注意的是,Xtrabackup2.4.x与8.0.x在第7、8这两个步骤存在差异,这个差异有MySQL8.0.x的原因,详情我们在下文介绍。
三、华为云RDSforMySQL备份在备份社区版MySQL实例时,Xtrabackup会对实例加全局读锁(FTWRL),该锁对数据库的业务影响很大,严重时甚至会导致数据库“挂起”,这对客户来说是不可接受的。因此华为云MySQL团队对这个过程进行了优化,主要有两点:
对MySQL5.x以及0.x增加了备份锁:LOCKTABLESFORBACKUP
对MySQL5.x新增了binlog锁:LOCKBINLOGFORBACKUP
优化之后,华为云Xtrabackup对MySQL的备份过程如下:
与FTWRL锁相比,备份锁LOCKTABLESFORBACKUP对客户实例影响很小,其加锁过程简单,加锁期间innodb表的DML操作不受影响,但是非innodb表的所有的更新操作以及DDL操作仍然是不允许的。
备份完所有的表文件后,Xtrabackup需要获取binlogGTID信息。
对于MySQL5.x版本,Xtrabackup2.4.x会执行LOCKBINLOGFORBACKUP操作,对binlog加锁,然后获取GTID信息。
对于MySQL8.0.x版本,华为云Xtrabackup8.0.x沿用官方的一致性备份点查询方法。Xtrabackup查询log_status时,MySQL服务器会分别对redolog,binlog等加轻量级锁,获取一致性备份点,这个过程是非常短暂的,对实例的运行几乎没有影响。MySQL8.0.x的备份一致性点,会告诉我们一致性的redologLSN以及binlog的GTID;查询完备份一致点后,Xtrabackup会备份最后一个binlog文件,用于恢复时仲裁事务是否需要回滚;最后,redolog备份线程任务会在其读取到的redolog的LSN大于查询到的备份一致性点的redologLSN处停止。
由于Xtrabackup2.4.x与8.0.x在处理binlog时存在差异,恢复过程也存在差异,我们会在后续文章中详细阐述。
四、常见问题与解决方法华为云已经使用Xtrabackup为公司几乎所有的MySQL实例提供备份服务,在使用过程中,我们积极与社区保持联系,向Percona社区报告使用过程中的一些问题,帮助Xtrabackup向更好的方向演进。此外,对于发现的一些致命问题,若社区未能及时修复,华为云数据库团队会进行及时修复以保证备份数据的正确性。
下面是我们总结在使用Xtrabackup备份过程各个阶段可能遇到的问题,分析其原因以及对应的解决方法,
1.兼容性检查阶段问题现象:Xtrabackup启动后,立即长时间“挂起”,查看日志发现redolog备份线程也没有启动。
原因:Xtrabackup兼容性检查时无法获取MDL锁。Xtrabackup兼容性检查是通过查询imformation_schema.tables这个插件表实现:
“SELECTCONCAT(table_schema,'/',table_name),engineFROMinformation_schema.tablesWHEREengineNOTIN('MyISAM','InnoDB','CSV','MRG_MYISAM')ANDtable_schemaNOTIN('performance_schema','information_schema','mysql')”
在查询每张表时,需要获取对应表的MDL锁,如果此时MySQL实例中存在长时间的DML或者DDL语句,或者更严重者出现了MDL死锁,上面的查询会一直堵塞在等待MDL锁阶段,此时Xtrabackup会长时间“挂起”。
解决办法:若等待锁的原因只是因为其他SQL语句的堵塞,等待其他SQL执行完成即可;若是发生了死锁,此时需要分析出死锁原因,将死锁解除;华为云RDSforMySQL提供了MDL锁视图功能,可以很好地帮助用户分析业务的MDL死锁。
2.redolog备份阶段问题现象1:redolog回卷,备份失败,Xtrabackup报如下错误信息:
“xtrabackup:error:itlookslikeInnoDBloghaswrappedaroundbeforextrabackupcouldprocessallrecordsduetoeitherlogcopyingbeingtooslow,orlogfilesbeingtoosmall.\n");”
原因:在备份的过程中,如果主机业务负载很高,导致redolog写入的速度很快,会发生Xtrabackup的redolog备份线程的备份速度小于redolog的写入速度,因为MySQLredolog文件写入使用了round-robin的方式,使得新写入的日志覆盖了之前写入却还未备份的日志,因此备份失败。
解决办法:推荐在业务低峰期进行备份,或者增大redolog的文件大小。
问题现象2:备份因DDL操作失败,错误信息如下:
“Anoptimized(withoutredologging)DDLoperationhasbeenperformed.Allmodifiedpagesmaynothavebeenflushedtothediskyet.
PXBwillnotbeabletakeaconsistentbackup.Retrythebackupoperation”
原因:备份过程中MySQL实例发生了创建索引的DDL操作,因为创建索引不会写redo,若继续备份会引起数据不一致问题,所以Xtrabackup在这种场景中备份失败是预期行为。
解决办法:不要在备份过程中创建索引,如果确实需要,建议在建表语句中直接带上索引,或者使用lock-ddl参数进行备份(阻塞实例上新的DDL操作)。
问题现象3:undotruncate导致备份失败,Xtrabackup错误信息如下:
“Anundoddltruncation(couldbeautomatic)operationhasbeenperformed.”
原因:在Xtrabackup备份期间,如果MySQL实例发生undotruncate时,有可能会出现写入新undo文件(spaceid不同)的undo日志丢失导致恢复出来的数据存在问题。官方在Xtrabackup8.0.14版本(基于MySQL8.0.21)对该问题进行了修复,修复方法是redo备份线程,解析redolog时若发现该操作是undolog的truncate操作,则会备份失败。遗憾的是,该修复并没有完全解决问题,在以下两种场景中,社区版本的Xtrabackup仍可能会发生恢复出来的数据存在不一致的现象:
MySQL版本低于MySQL8.0.21;
用户在备份过程中,自己创建了新的undotablespace。
解决办法:在备份期间关闭undotablespace的truncate操作,并禁止用户创建undotablespace,能够有效地防止备份数据恢复出来不一致的问题;另外华为云Xtrabackup对这个问题进行了进一步的修复,可以有效地防止此类现象发生。
3.加载表空间阶段问题现象1:Xtrabackup报错:Toomanyopenfiles
原因:操作系统允许同时打开的文件数量是有限的,Xtrabackup在loadtablespace阶段会同时打开所有的表文件,如果Xtrabackup打开的表的个数超过了该限制,则会备份失败。
解决办法:调大操作系统,允许同时打开最大文件数的配置,或者使用lock-ddl参数(阻塞实例上新的DDL操作)。
问题现象2:renametable导致备份失败,错误信息如下:
“Tryingtoaddtablespace'xxxx'withidxxxtothetablespacememorycache,buttablespacexxxxalreadyexistsinthecache!;”
原因:在Xtrabackup打开表空间的全过程是没有加锁的,如果发生了renametable有概率会发生重复加载相同的表空间,此时Xtrabackup会检测到重复的tablespaceid,因此备份失败。
解决办法:一般来说,加载表空间是一个很快的操作,renametable并不是一个很频繁的操作,这种情况重试即可(PerconaXtrabackup2.4.x仅支持单线程加载表空间,华为云Xtrabackup支持多线程加载表空间)。
4.备份innodb表阶段问题现象:innodb表数据文件损坏,备份失败,错误信息如下:
“xtrabackup:Databasepagecorruptiondetectedatpagexxxx,retrying.”
原因:Xtrabackup在备份innodb表数据文件时,会检查每个页面的checksum,如果发现checksum不对,则备份失败,这时说明MySQL实例的数据已经发生了损坏(例如磁盘静默错误)。
解决办法:需要通过恢复前一次的备份数据或者其他的办法将数据进行修复之后,备份才能成功,在后续的文章中,我们也会详细介绍数据修复办法。
五、结语本文主要对比介绍了Xtrabackup备份原理,备份社区版MySQL以及华为云对其的改进,并分享了Xtrabackup常见问题的排查与解决,后续我们也会为大家带来更深入的分析,更实用的使用技巧,希望对大家理解和使用Xtrabackup有帮助。我们也将持续为客户提供更好的数据库服务,并时刻守护客户的数据安全。