首页域名资讯 正文

Xtrabackup 每日增量恢复 – Awaken

2024-10-15 1 0条评论

前言

此恢复程序应该和上次发布的“Xtrabackup每周增量备份脚本程序”配合使用。http://www.trustauth.cn/mysql/xtrabackup-daily-backup/。本程序正式命名为:Awaken

程序用途

对于我个人来说使用每日增量恢复主要是有两个用途:

  • 用途1:为了验证备份的备份集是否有效,会不会出现备份不可用的情况。
  • 用途2:如果出现了线上误操作,更快的能找出误操作的数据并进行恢复(一般恢复库的数据总是比线上的晚1到2天)。

(提示:用途2的场景你也可以使用mysql主从来实现,通过start slave until等语法 + crontab。这里不多说)

程序结构

此程序包含了4个目录(bin、conf、log、var):

  • bin:存放运行恢复的主脚本程序(*.sh)。
  • conf:存放着程序运行的配置文件变量(*.conf)。
  • log:存放的是恢复时xtrabackup的输出内容(*.log)。
  • var:存放了索引文件(*.index)和错误记录文件(*.err)。
  1. *.index:每当恢复成功后都会记录一条信息到此文件中,此文件也是增量恢复的一个基础文件,当恢复的是增量的备份集,需要到*.index文件中找到第一次全备的记录作为增量恢复的基础。
  2. *.err:每当恢复出错了会记录一条数据到此文件。如果需要对恢复成功与否进行监控,可以通过此文件的变化来判断是否恢复成功(文件无变化就是备份成功了)。

(提示:这边的结果其实是和“Xtrabackup每周增量备份脚本程序”一致)

 

先决条件

确保你的xtrabackup 程序在机器上已经可以正确使用。

注意事项

为了安全请使用root以外的用户来使用本程序,本人专门使用了一个mysql用户来执行mysql相关的操作。

程序流程图

awaken流程

使用方式

一般此程序是配合crontab来每天执行的。

  • 执行

#         你的程序路径

/bin/bash /tmp/xtrabackup_cron/bin/recover.sh

(提示:有时候可能需要手动执行recover.sh脚本,可以指定文件/bin/bash recover.sh xx.tar.bz2。其中xx.tar.bz2需要在你配置文件中的备份目录)

 

  • 恢复成功索引文件内容

# 恢复成功 索引文件内容

{week_day:3,  dir:full_2015-12-31_20-11-36_4,  type:full,  date:2016-01-01 00:00:00}

{week_day:3,  dir:incr_2015-12-31_20-13-50_4,  type:incr,  date:2016-01-01 00:30:00}

  • 恢复失败错误文件内容

# 恢复失败 索引文件内容

{week_day:3, file_name:full_2015-12-31_20-11-36_4.tar.bz2, type:full, date:2016-01-01 00:10:00}

{week_day:3, file_name:incr_2015-12-31_20-13-50_4.tar.bz2, type:incr, date:2016-01-01 00:20:00}

(提示:其实索引文件的内容格式和错误文件的一样)

程序展示

  • 配置文件conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 # 备份路劲 recover_dir = / tmp / recover # 备份路劲文件所在的路径 backup_dir = / tmp / backup # percona-xtrabackup 备份软件路径 xtrabackup_dir = / usr / local / percona xtrabackup # 恢复几天前的备份 # 0:今天,1:昨天 # 如果选择1,恢复时间是2016-01-01 00:00:00, 恢复的是2015-12-31那一天备份的 # 如果选择0,恢复时间是2016-01-01 00:00:00, 恢复的是2016-01-01那一天备份的, #           因此可能会报错,因为还没备份。 n_day_ago = 1 # 全量备信息名称 前缀 full_recover_prefix = full # 增量备信息名称 前缀 increment_prefix = incr # 增量备信息名称 前缀 backup_file_suffix = . tar . bz2 # 错误日志文件(更具此文件知道备份是否成功) # format: # {week_day:1,file_name:full/incr_2015-12-29_00-00-00_7.tar.bz2,type:full/incr,date:2015-12-30 00:00:00} error_log = recover . err # 索引文件 # format: # {week_day:1,dir:full/incr_2015-12-29_00-00-00_7,type:full/incr,date:2015-12-30 00:00:00} index_file = recover . index
  • 主程序说明

程序说明这里分4个模块来看(主逻辑、变量初始化、检测配置文件正确性、使用的其他方法)

  1. 主逻辑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 function run ( ) {    #执行检测配置文件正确性    test_conf_file    # 备份错误日志文件    error_log = $ program_dir / var / ` sed ‘/^error_log=/!d;s/.*=//’ $ conf_file `    # 备份索引文件    index_file = $ program_dir / var / ` sed ‘/^index_file=/!d;s/.*=//’ $ conf_file `    if [ $ # -eq 1 ]; then      backup_file = $ 1    else      backup_file =    fi    # 获得备份文件 可以传参数:full_2015-12-31_20-11-36_4.tar.bz2    get_backup _file $ backup_file    # 获得恢复文件夹名称    get_recover _folder $ backup_file    # 获得备份类型    get_recover_type    case $ recover_type in      full )        # 解压备份文件        tar_file_to _dir $ backup_file        # 应用恢复        apply_log _full $ recover_folder        # 备份索引文件        backup_index_file        # 删除之前的恢复        delete_before_recover        # 清楚索引文件        purge_index_from_file        # 添加索引文件        append_index_to _file $ recover _folder $ recover _type        ; ;      incr )        # 解压备份文件        tar_file_to _dir $ backup_file        # 应用恢复        apply_log _incr $ recover_folder        # 添加索引文件        append_index_to _file $ recover _folder $ recover _type        ; ;      *      )        logging_err file_err file_named_err        exit 2    esac } if [ $ # -eq 1 ]; then    run $ 1 else    run fi

2. 变量初始化

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 # 获得程序路径名 program_dir = ` dirname $ 0 ` / . . # 读取配置文件中的所有变量值, 设置为全局变量 # 配置文件 conf_file = “$program_dir/conf/recover.conf” # mysql 恢复目录 recover_dir = ` sed ‘/^recover_dir=/!d;s/.*=//’ $ conf_file ` # mysql 备份目录 backup_dir = ` sed ‘/^backup_dir=/!d;s/.*=//’ $ conf_file ` # percona-xtrabackup 备份软件路径 xtrabackup_dir = ` sed ‘/^xtrabackup_dir=/!d;s/.*=//’ $ conf_file ` # 全备是在一周的第几天 n_day_ago = ` sed ‘/^n_day_ago=/!d;s/.*=//’ $ conf_file ` # mysql 全备前缀标识 full_recover_prefix = ` sed ‘/^full_recover_prefix=/!d;s/.*=//’ $ conf_file ` # mysql 增量备前缀标识 increment_prefix = ` sed ‘/^increment_prefix=/!d;s/.*=//’ $ conf_file ` # mysql 增量备前缀标识 backup_file_suffix = ` sed ‘/^backup_file_suffix=/!d;s/.*=//’ $ conf_file ` # 备份错误日志文件 error_log = ` sed ‘/^error_log=/!d;s/.*=//’ $ conf_file ` # 备份索引文件 index_file = ` sed ‘/^index_file=/!d;s/.*=//’ $ conf_file ` # 备份日期 recover_date = ` date + % F ` # 备份日期 recover_time = ` date + % H : % M : % S ` # 备份日期 recover_week_day = ` date + % u ` # 获得需要恢复的备分日期 backup_date = ` date d “$n_day_ago day ago” + % F ` # 创建相关目录 log_dir = $ program_dir / log / recover var_dir = $ program_dir / var mkdir p $ recover_dir mkdir p $ log_dir mkdir p $ var_dir

3. 检测配置文件正确性

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 # 测试配置文件正确性 function test_conf_file ( ) {    test_ok = 0    # 判断每个变量是否在配置文件中有配置,没有则退出程序    if [ ! n “$recover_dir” ] ; then echo ‘fail: configure file recover_dir not set’ ; test_ok = 1 ; fi    if [ ! n “$backup_dir” ] ; then echo ‘fail: configure file backup_dir not set’ ; test_ok = 1 ; fi    if [ ! n “$xtrabackup_dir” ] ; then echo ‘fail: configure file xtrabackup_dir not set’ ; $ test_ok = 1 ; fi    if [ ! n “$n_day_ago” ] ; then echo ‘fail: configure file n_day_ago not set’ ; test_ok = 1 ; fi    if [ ! n “$full_recover_prefix” ] ; then echo ‘fail: configure file full_backup_prefix not set’ ; test_ok = 1 ; fi    if [ ! n “$increment_prefix” ] ; then echo ‘fail: configure file increment_prefix not set’ ; test_ok = 1 ; fi    if [ ! n “$backup_file_suffix” ] ; then echo ‘fail: configure file backup_file_suffix not set’ ; test_ok = 1 ; fi    if [ ! n “$error_log” ] ; then echo ‘fail: configure file error_log not set’ ; test_ok = 1 ; fi    if [ ! n “$index_file” ] ; then echo ‘fail: configure file index_file not set’ ; test_ok = 1 ; fi    if [ 1 eq $ test _ok ] ; then      logging_err null test_conf_file      exit 2    fi }

4. 使用的其他方法

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 # 准备全量恢复 function apply_log_full ( ) {    echo $ log_dir / $ { 1 } . log    $ xtrabackup_dir / bin / innobackupex \      apply log \      redo only \      $ recover_dir / $ 1 > $ log_dir / $ { 1 } . log 2 > & 1    if [ $ ? ne 0 ] ; then      logging _err $ backup_file apply_log_err      exit 2    fi } # 准备增量恢复 function apply_log_incr ( ) {    # 获得增量 base 路径    get_incr_base    echo $ log_dir / $ { 1 } . log    $ xtrabackup_dir / bin / innobackupex \      apply log \      redo only \      $ recover_dir / $ base _dir \      incremental dir = $ { recover_dir } / $ { 1 } > $ log_dir / $ { 1 } . log 2 > & 1    if [ $ ? ne 0 ] ; then      logging _err $ backup_file incr_recover_err      exit 2    fi } # 获得增量 base 路径 function get_incr_base ( ) {    base_dir = ` grep ‘type:full’ $ index_file | \              sed n ‘1p’ | \              awk F ‘[, {}]*’ ‘{print $3}’ | \              awk F ‘:’ ‘{print $2}’ ` } # 获得备份文件名 get_backup_file ( ) {    if [ $ # -eq 1 ]; then      backup_file = ` basename $ 1 `    else      backup_file = ` find $ backup_dir maxdepth 1 type f name “*$backup_file_suffix” | \                  grep $ backup_date | \                  sed n ‘$p’ | \                  xargs basename `    fi    if [ ! n “$backup_file” ] ; then      logging_err no_file cannot_find_file      exit 2    fi } # 获得恢复文件夹名称 get_recover_folder ( ) {    recover_folder = ` basename s $ backup_file _suffix $ 1 ` } # 获得恢复类型 get_recover_type ( ) {    recover_type = ` echo $ recover_folder | awk F ‘_’ ‘{print $1}’ `    if [ $ # -eq 1 ]; then      recover_type = $ 1    elif [ “full” = “$recover_type” ] ; then      recover_type = full    elif [ “incr” = “$recover_type” ] ; then      recover_type = incr    else      logging_err no_file type_not_in_range      exit 2    fi } # 解压文件到恢复目录 function tar_file_to_dir ( ) {    if [ d “$recover_dir/$recover_folder” ] ; then      # logging_err $backup_file recover_folder_already_exists      rm rf $ recover_dir / $ recover_folder    fi    tar jxf $ backup_dir / $ 1 C $ recover _dir } # 记录错误日志 function logging_err ( ) {    error_log = $ program_dir / var / ` sed ‘/^error_log=/!d;s/.*=//’ $ conf_file `    echo “{week_day:$recover_week_day, \          file_name:${1}, \          type:${2}, \          time:${recover_date} ${recover_time}}” >> $ error _log } # 备份索引文件 function backup_index_file ( ) {    if [ f “$index_file” ] ; then      cp $ index_file $ { index_file } _ $ ( date d “$n_day_ago day ago” + % F )    fi } # 删除之前的备份(一般在全备完成后使用) function delete_before_recover ( ) {    cat $ index_file | awk F ‘[, {}]*’ ‘{print $3}’ | \      awk v backup_dir = $ backup_dir F ‘:’ ‘{if($2!=””){printf(“rm -rf %s/%s\n”, backup_dir, $2)}}’ | \      / bin / bash    cat $ index_file | awk F ‘[, {}]*’ ‘{print $3}’ | \      awk v log_dir = $ log_dir F ‘:’ ‘{if($2!=””){printf(“rm -rf %s/%s.log\n”, log_dir, $2)}}’ | \      / bin / bash } # 清空索引 function purge_index_from_file ( ) {    if [ f “$index_file” ] ; then      > $ index_file    fi } # 添加索引, 索引记录了当前最新的备份 function append_index_to_file ( ) {    echo “{week_day:$recover_week_day, \          dir:${1}, \          type:${2}, \          date:${backup_date}}” >> $ index _file }

在我的机器上我将我的备份文件使用*.tar.bz2的压缩文件,因此我的配置文件的backup_file_suffix=.tar.bz2。你可以更具你自己而定。如果你没有使用压缩文件而是指定备份文件目录则可以将 apply_log_full 和 apply_log_incr 两个方法注释掉。

文章转载来自:trustauth.cn

文章版权及转载声明

本文作者:亿网 网址:https://edns.com/ask/post/150729.html 发布于 2024-10-15
文章转载或复制请以超链接形式并注明出处。