连延迟从库都用不上了,MySQL备份还能恢复吗?

徐晨亮 2020-10-10 10:30:41
 
​背景

 

首先交代一下背景,由于某些因素的限制,我们公司目前的备份策略采用的是隔天全备的方案,增量备份则使用的是binlog server的方式,那么如何快速恢复就成为了我们需要思考的问题。

 

正文

 

恢复需求
 

 

根据我以往的一些经验来说,通常需要从备份恢复数据的场景有如下几种:

 

  • 被误删库了;

  • 被误删表了,类型为TRUNCATE或者DROP;

  • 被误删列了,类型为ALTER ... DROP COLUMN;

  • 被误删数据了,类型为DELETE或者UPDATE或者REPLACE;

  • 表空间损坏或出现坏块了。

 

根据场景来说,我们可以大致分为两类:

 

第一类为不可逆恢复,也就是通常的DDL,比如上述的1、2、3、5等场景;

第二类为可逆的恢复,通常可以利用binlog进行回滚(要求binlog格式为ROW,binlog_image为FULL),也就是对应上述的场景4。

 

对于第二类的恢复需求一般来说都比较容易处理,可以利用binlog回滚工具,例如业界比较著名的有binlog2sql以及MyFlash等,这里暂不赘述,我们重点来讨论第一类需求。

 

为了达到快速恢复的目的,业界DBA经常会采用的方式就是部署一个延迟从库来解决,我们公司目前所有的核心DB都部署了延迟从库。但是即便有了延迟从库,假设我们错过了延迟的时间,或者在后续利用延迟从库恢复的时候指定错了位点,导致了误删DDL同样应用到了从库,这个时候我们就没有办法利用延迟从库这根救命稻草了。

 

全备恢复(异机恢复)
 

 

此时,我们只能通过备份来进行数据恢复了。首先我们需要恢复全备,通常来说就是xtrabackup备份的物理备份了。假设你的备份在远程的机器上,那么你可能需要做如下几步动作来进行全备恢复:

 

  • 将备份scp或者rsync到目标实例机器上;

  • 假设备份文件是压缩的情况下,需要解压;

  • 解压完成后,需要apply redo log;

  • 更改文件权限;

  • 假设你直接将文件拷贝到的目标实例的datadir目录下,那么这一步你就可以直接启动mysqld,假设不是,那么你还需要将数据文件move-back或者copy-back到目标实例的datadir;

  • 实例启动。

 

增备恢复
 

 

到这里,全备已经恢复完成了,接下来需要做的就是增量恢复了。按照我们之前的备份方案,我们需要通过binlog来完成增量数据的恢复。对于binlog恢复,我们通常需要以下几个步骤:

 

  • 确定全备对应的binlog位点,也就是需要恢复的起始点;

  • 解析主库的binlog,确定误删数据的位点,作为我们恢复的终点;

  • 利用mysqlbinlog —start-position —stop-position+管道的方式,将binlog恢复到目标实例上。

 

binlog恢复的方式有很多种,你可以用的是原先master上的binlog,也可以用binlogserver上的binlog,需要做的就是找到binlog恢复的终点即可。

 

增备恢复优化
 

 

到这里,你可能会觉得,利用binlog恢复有点麻烦。确实是这样的,利用mysqlbinlog命令并没有办法指定恢复到哪个GTID,只能通过解析binlog,找到需要恢复到的GTID对应的pos位点才行,这对于自动化来说实现起来会比较麻烦。另外,如果利用mysqlbinlog命令恢复,属于单线程恢复,假设需要恢复的binlog量比较多的话,那么这个增量恢复的时间可想而知。

 

那么有什么办法能加速binlog应用呢?这里我们就想到了MySQL5.7的并行复制(假如你是5.6版本的话,由于是基于database的并行复制,并不能使用到“并行”的特性),如果我们能用到sql thread的并行复制,是不是这个问题就解决了呢?

 

master上binlog恢复
 

 

我们回到全备恢复的位点,我们将新实例作为原先的master的slave,然后恢复到指定的GTID位置就可以了呢?没错,这是一种非常简便又轻松还不容易出错的方式,并且还可以利用并行复制的原理来加速binlog应用的目的。但是这种方式的一个前提条件就是原先的master最老的binlog包含了我们需要的起始恢复位点,这个很容易想到,所以,这将成为我们首选的恢复方式。

 

binlogserver上binlog恢复
 

 

假设原先master上的binlog已经被purge了,那么我们那需要从binlog上去恢复。有人可能会想到将binlogserver上的binlog拷贝到原先的master上,然后通过修改binlog index来达到注册的目的,实际上这并不可取,具体原因可以见《手动注册binlog文件造成主从异常》

 

我们可以采取的方式是什么呢?就是利用binlogserver做成伪装master,然后将从库change上去,其思想就是欺骗slave,让slave的io_thread将缺失的binlog拉取过来,sql_thread并行应用binlog event(我们将在下一节具体演示这种方式)。

 

优化后的恢复流程
 

 

经过优化以后,我们的增备恢复流程就变成了,首先通过master上的binlog进行恢复,如果发现master上的binlog已经被purge了,那么通过binlogserver上的binlog进行恢复,这样一来我认为是比较科学合理的恢复流程。

 

各种恢复方式时效性对比
 

 

 

业务恢复
 

 

到这里,我们已经完成了全量+增量的备份数据恢复,这个时候需要同研发确认数据,确认完成以后将对应的表恢复到原先的master,通常采用的方式有:

 

  • mysqldump导出+导入目标实例;

  • 表空间传输。

 

总结

 

本节主要介绍了备份恢复的设计流程,在我们没有办法优化全备恢复的情况下,我们通过优化增量备份方式和流程达到缩短恢复时间的目的。并且需要说明的一点是,本节介绍的目前我还没有完全测试,不保证每个点都是正确的,还需要进一步验证,验证通过以后我也会通知大家,并且结合到现有的数据库运维平台,做到自动化恢复。

 

最后还是提醒几点:

 

  • 数据是无形的财产,请广大DBA朋友务必做好备份并做好备份验证;

  • 如果有条件的情况下,尽量部署延迟从库;

  • 做好恢复预案,免得恢复的时候手忙脚乱,菊花打紧;

  • 根据场景选择合适的恢复手段,尽量缩短恢复时间。

 

作者丨徐晨亮
来源丨mysql code tracer(ID:mysqlcodetracer)
dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn
 
​背景

 

首先交代一下背景,由于某些因素的限制,我们公司目前的备份策略采用的是隔天全备的方案,增量备份则使用的是binlog server的方式,那么如何快速恢复就成为了我们需要思考的问题。

 

正文

 

恢复需求
 

 

根据我以往的一些经验来说,通常需要从备份恢复数据的场景有如下几种:

 

  • 被误删库了;

  • 被误删表了,类型为TRUNCATE或者DROP;

  • 被误删列了,类型为ALTER ... DROP COLUMN;

  • 被误删数据了,类型为DELETE或者UPDATE或者REPLACE;

  • 表空间损坏或出现坏块了。

 

根据场景来说,我们可以大致分为两类:

 

第一类为不可逆恢复,也就是通常的DDL,比如上述的1、2、3、5等场景;

第二类为可逆的恢复,通常可以利用binlog进行回滚(要求binlog格式为ROW,binlog_image为FULL),也就是对应上述的场景4。

 

对于第二类的恢复需求一般来说都比较容易处理,可以利用binlog回滚工具,例如业界比较著名的有binlog2sql以及MyFlash等,这里暂不赘述,我们重点来讨论第一类需求。

 

为了达到快速恢复的目的,业界DBA经常会采用的方式就是部署一个延迟从库来解决,我们公司目前所有的核心DB都部署了延迟从库。但是即便有了延迟从库,假设我们错过了延迟的时间,或者在后续利用延迟从库恢复的时候指定错了位点,导致了误删DDL同样应用到了从库,这个时候我们就没有办法利用延迟从库这根救命稻草了。

 

全备恢复(异机恢复)
 

 

此时,我们只能通过备份来进行数据恢复了。首先我们需要恢复全备,通常来说就是xtrabackup备份的物理备份了。假设你的备份在远程的机器上,那么你可能需要做如下几步动作来进行全备恢复:

 

  • 将备份scp或者rsync到目标实例机器上;

  • 假设备份文件是压缩的情况下,需要解压;

  • 解压完成后,需要apply redo log;

  • 更改文件权限;

  • 假设你直接将文件拷贝到的目标实例的datadir目录下,那么这一步你就可以直接启动mysqld,假设不是,那么你还需要将数据文件move-back或者copy-back到目标实例的datadir;

  • 实例启动。

 

增备恢复
 

 

到这里,全备已经恢复完成了,接下来需要做的就是增量恢复了。按照我们之前的备份方案,我们需要通过binlog来完成增量数据的恢复。对于binlog恢复,我们通常需要以下几个步骤:

 

  • 确定全备对应的binlog位点,也就是需要恢复的起始点;

  • 解析主库的binlog,确定误删数据的位点,作为我们恢复的终点;

  • 利用mysqlbinlog —start-position —stop-position+管道的方式,将binlog恢复到目标实例上。

 

binlog恢复的方式有很多种,你可以用的是原先master上的binlog,也可以用binlogserver上的binlog,需要做的就是找到binlog恢复的终点即可。

 

增备恢复优化
 

 

到这里,你可能会觉得,利用binlog恢复有点麻烦。确实是这样的,利用mysqlbinlog命令并没有办法指定恢复到哪个GTID,只能通过解析binlog,找到需要恢复到的GTID对应的pos位点才行,这对于自动化来说实现起来会比较麻烦。另外,如果利用mysqlbinlog命令恢复,属于单线程恢复,假设需要恢复的binlog量比较多的话,那么这个增量恢复的时间可想而知。

 

那么有什么办法能加速binlog应用呢?这里我们就想到了MySQL5.7的并行复制(假如你是5.6版本的话,由于是基于database的并行复制,并不能使用到“并行”的特性),如果我们能用到sql thread的并行复制,是不是这个问题就解决了呢?

 

master上binlog恢复
 

 

我们回到全备恢复的位点,我们将新实例作为原先的master的slave,然后恢复到指定的GTID位置就可以了呢?没错,这是一种非常简便又轻松还不容易出错的方式,并且还可以利用并行复制的原理来加速binlog应用的目的。但是这种方式的一个前提条件就是原先的master最老的binlog包含了我们需要的起始恢复位点,这个很容易想到,所以,这将成为我们首选的恢复方式。

 

binlogserver上binlog恢复
 

 

假设原先master上的binlog已经被purge了,那么我们那需要从binlog上去恢复。有人可能会想到将binlogserver上的binlog拷贝到原先的master上,然后通过修改binlog index来达到注册的目的,实际上这并不可取,具体原因可以见《手动注册binlog文件造成主从异常》

 

我们可以采取的方式是什么呢?就是利用binlogserver做成伪装master,然后将从库change上去,其思想就是欺骗slave,让slave的io_thread将缺失的binlog拉取过来,sql_thread并行应用binlog event(我们将在下一节具体演示这种方式)。

 

优化后的恢复流程
 

 

经过优化以后,我们的增备恢复流程就变成了,首先通过master上的binlog进行恢复,如果发现master上的binlog已经被purge了,那么通过binlogserver上的binlog进行恢复,这样一来我认为是比较科学合理的恢复流程。

 

各种恢复方式时效性对比
 

 

 

业务恢复
 

 

到这里,我们已经完成了全量+增量的备份数据恢复,这个时候需要同研发确认数据,确认完成以后将对应的表恢复到原先的master,通常采用的方式有:

 

  • mysqldump导出+导入目标实例;

  • 表空间传输。

 

总结

 

本节主要介绍了备份恢复的设计流程,在我们没有办法优化全备恢复的情况下,我们通过优化增量备份方式和流程达到缩短恢复时间的目的。并且需要说明的一点是,本节介绍的目前我还没有完全测试,不保证每个点都是正确的,还需要进一步验证,验证通过以后我也会通知大家,并且结合到现有的数据库运维平台,做到自动化恢复。

 

最后还是提醒几点:

 

  • 数据是无形的财产,请广大DBA朋友务必做好备份并做好备份验证;

  • 如果有条件的情况下,尽量部署延迟从库;

  • 做好恢复预案,免得恢复的时候手忙脚乱,菊花打紧;

  • 根据场景选择合适的恢复手段,尽量缩短恢复时间。

 

作者丨徐晨亮
来源丨mysql code tracer(ID:mysqlcodetracer)
dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn
 

 

2020 DAMS中国数据智能管理峰会即将于10月30日在上海举办,部分精彩议题先睹为快:

 
  • 腾讯《腾讯游戏大数据资产管理实战:元数据管理与数据治理

  • 京东《京东EB级全域大数据平台建设和治理之路》

  • 阿里《大规模容器云基础设施环境架构、管理与运维》

  • 工商银行《DevOps转型的探索与实践》

  • 中国银联《从自研演进看分布式数据库》

  • 民生银行《开源数据库MySQL在民生银行的应用实践》

  • 平安银行《“传统+互联网”混合CMDB及运营中台实践》

  • 中国联通《大数据资产管理平台的设计、研发、运营实践》

  • AWS《基于数据湖构建云上的数据分析架构》

  • 今日头条字节跳动数据治理实践》

  • 苏宁《苏宁大规模智能告警收敛与告警根因的实践》

  • 滴滴《万亿级消息队列Kafka在滴滴的实践》

 

活动预告