MySQL如何使用使用Xtrabackup进行备份和恢复

作者:Frost Boy 时间:2024-01-24 14:45:49 

1 备份

进行备份前需要先创建备份用户,直接使用 root 用户进行备份也行,但是这样不太规范。


   create user backup@'localhost' identified by '123456';
   grant reload,process,lock tables,replication client on *.* to backup@localhost;

1.1 全备

备份整个库,使用的是备份用户,备份文件存放地址为 /backup/


   innobackupex --defaults-file=/etc/my.cnf --user=backup --password=123456 /backup/

1.2 增备

指定为增量备分,使用的是备份用户,增量的基础为上一次的全备,已经使用 --incremental-basedir 进行指定了,备份后存放的文件为 /backup/


   innobackupex --defaults-file=/etc/my.cnf --user=backup --password=123456 --incremental --incremental-basedir=/backup/2021-06-01_14-44-54 /backup/

2 备份恢复

2.1 准备数据

回滚未提交的事务及同步已经提交的事务至数据文件使数据文件处于一致性状态


   innobackupex --apply-log --redo-only /backup/2021-06-01_14-44-54/

2.2 进行恢复

在恢复前,需要确保 MySQL 的数据目录为已经删除了。


   innobackupex --copy-back --datadir=/usr/local/mysql/data /backup/2021-06-01_14-44-54/

恢复后,需要对 MySQL 的data 目录进行重新赋权:


   chown -R mysql:mysql data/

到这恢复就完成了。

3 目录结构

MySQL如何使用使用Xtrabackup进行备份和恢复

4 备份脚本

4.1 脚本

backup.sh


   #!/bin/bash
   # 获得程序路径名
   program_dir=`dirname $0`/..
   # 读取配置文件中的所有变量值, 设置为全局变量
   # 配置文件
   conf_file="$program_dir/conf/backup.conf"
   # mysql 用户
   user=`sed '/^user=/!d;s/.*=//' $conf_file`
   # mysql 密码
   password=`sed '/^password=/!d;s/.*=//' $conf_file`
   # mysql 备份目录
   backup_dir=`sed '/^backup_dir=/!d;s/.*=//' $conf_file`
   # mysql 备份压缩打包目录
   gzip_dir=`sed '/^gzip_dir=/!d;s/.*=//' $conf_file`
   # percona-xtrabackup命令xtrabackup路径
   xtrabackup_bin=`sed '/^xtrabackup_bin=/!d;s/.*=//' $conf_file`
   # mysql 全备前缀标识
   full_backup_prefix=`sed '/^full_backup_prefix=/!d;s/.*=//' $conf_file`
   # mysql 增量备前缀标识
   increment_prefix=`sed '/^increment_prefix=/!d;s/.*=//' $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`
   # 备份日期
   backup_date=`date +%F`
   # 备份时间
   backup_time=`date +%H-%M-%S`
   # 备份时的周几
   backup_week_day=`date +%u`
   # 创建相关目录
   log_dir=$program_dir/log/backup
   var_dir=$program_dir/var
   mkdir -p $backup_dir
   mkdir -p $log_dir
   mkdir -p $var_dir
   mkdir -p $gzip_dir
   # 全量备份
   function full_backup() {
     backup_folder=${full_backup_prefix}_${backup_date}_${backup_time}_${backup_week_day}
     mkdir -p $backup_dir/$backup_folder
     $xtrabackup_bin \
       --user=$user \
       --password=$password \
       --backup \
       --target-dir=$backup_dir/$backup_folder > $log_dir/${backup_folder}.log 2>&1
     return $?
   }
   # 增量备份
   function increment_backup() {
     backup_folder=${increment_prefix}_${backup_date}_${backup_time}_${backup_week_day}
     incr_base_folder=`sed -n '$p' $index_file | \
                      awk -F '[, {}]*' '{print $3}' | \
                      awk -F ':' '{print $2}'`
     mkdir -p $backup_dir/$backup_folder
     $xtrabackup_bin \
       --user=$user \
       --password=$password \
       --backup \
       --target-dir=$backup_dir/$backup_folder \
       --incremental-basedir=$backup_dir/$incr_base_folder > $log_dir/${backup_folder}.log 2>&1
     return $?
   }
   # 删除之前的备份(一般在全备完成后使用)
   function delete_before_backup() {
     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 gzip_dir=$gzip_dir -F ':' '{if($2!=""){printf("rm -rf %s/%s\n", gzip_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 backup_index_file() {
     cp $index_file ${index_file}_$(date -d "1 day ago" +%F)
   }
   # 备份索引文件
   function send_index_file_to_remote() {
     # ./expect_scp ip地址 账号 密码  ${index_file} 目标服务器存放的文件夹 端口号
     echo 'send index file ok'
   }
   # 添加索引, 索引记录了当前最新的备份
   function append_index_to_file() {
     echo "{week_day:$backup_week_day, \
            dir:${1}_${backup_date}_${backup_time}_${backup_week_day}, \
            type:${1}, \
            date:${backup_date}}" >> $index_file
   }
   # 记录错误消息到文件
   function logging_backup_err() {
     echo "{week_day:$backup_week_day, \
            dir:${1}_${backup_date}_${backup_time}_${backup_week_day}, \
            type:${1}, \
            date:${backup_date}}" >> $error_log
   }
   # 清空索引
   function purge_index_from_file() {
     > $index_file
   }
   # 清空错误日志信息
   function purge_err_log() {
     > $error_log
   }
   # 打包备份
   function tar_backup_file() {
     cd $backup_dir
     tar -jcf ${gzip_dir}/${1}_${backup_date}_${backup_time}_${backup_week_day}.tar.bz2 \
              ${1}_${backup_date}_${backup_time}_${backup_week_day}
     cd - > /dev/null
     rm -rf ${backup_dir}/${1}_${backup_date}_${backup_time}_${backup_week_day}
   }
   # 发送备份到远程
   function send_backup_to_remote() {
     #  ./expect_scp ip地址 账号 密码 ${gzip_dir}/${1}_${backup_date}_${backup_time}_${backup_week_day}.tar.bz2 目标服务器存放的文件夹 端口号
     echo "send $1 remote ok"
   }
   # 判断是应该全备还是增量备份
   # 0:full, 1:incr
   function get_backup_type() {
     backup_type=0
     if [ 1 -eq `date +%H` ]; then
       backup_type=0
     else
       backup_type=1
     fi
     touch $index_file
     if [ ! -n "`cat $index_file`" ]; then
       backup_type=0
     fi
     return $backup_type
   }
   # 测试配置文件正确性
   function test_conf_file() {
     # 判断每个变量是否在配置文件中有配置,没有则退出程序
     if [ ! -n "$user" ]; then echo 'fail: configure file user not set'; exit 2; fi
     if [ ! -n "$password" ]; then echo 'fail: configure file password not set'; exit 2; fi
     if [ ! -n "$backup_dir" ]; then echo 'fail: configure file backup_dir not set'; exit 2; fi
     if [ ! -n "$gzip_dir" ]; then echo 'fail: configure file backup_dir not set'; exit 2; fi
     if [ ! -n "$full_backup_prefix" ]; then echo 'fail: configure file full_backup_prefix not set'; exit 2; fi
     if [ ! -n "$increment_prefix" ]; then echo 'fail: configure file increment_prefix not set'; exit 2; fi
     if [ ! -n "$error_log" ]; then echo 'fail: configure file error_log not set'; exit 2; fi
     if [ ! -n "$index_file" ]; then echo 'fail: configure file index_file not set'; exit 2; fi
   }
   # 执行
   function main() {
     # 检测配置文件值
     test_conf_file
     # 判断是执行全备还是增量备份
     get_backup_type
     backup_type=$?
     case $backup_type in
       0 )
         # 全量备份
         full_backup
         backup_ok=$?
         if [ 0 -eq "$backup_ok" ]; then
         # 全备成功
           # 打包最新备份
           tar_backup_file $full_backup_prefix
           # # 将tar备份发送到远程
           send_backup_to_remote $full_backup_prefix
           # 备份索引文件
           backup_index_file
           # 清除之前的备份
           delete_before_backup
           # 清除索引文件
           purge_index_from_file
           # 添加索引, 索引记录了当前最新的备份
           append_index_to_file $full_backup_prefix
           # 发送索引文件到远程
           send_index_file_to_remote
         else
         # 全备失败
           # 删除备份目录
           rm -rf ${backup_dir}/${full_backup_prefix}_${backup_date}_${backup_time}_${backup_week_day}
           # 记录错误日志
           logging_backup_err $full_backup_prefix
         fi
         ;;
       1 )
         # 增量备份
         increment_backup
         backup_ok=$?
         if [ "$backup_ok" -eq 0 ]; then
         # 增量备份成功
           # 打包最新备份
           tar_backup_file $increment_prefix
           # # 将tar备份发送到远程
           send_backup_to_remote $increment_prefix
           # 添加索引, 索引记录了当前最新的备份
           append_index_to_file $increment_prefix
           # # 发送索引文件到远程
           send_index_file_to_remote
         else
         # 增量备份失败
           # 删除备份目录
           rm -rf ${backup_dir}/${increment_prefix}_${backup_date}_${backup_time}_${backup_week_day}
           # 记录错误日志
           logging_backup_err $increment_prefix
         fi
         ;;
     esac
   }
   main

4.2 配置文件

backup.conf


   # mysql 用户名
   user=backup
   # mysql 密码
   password=123456
   # 备份路径
   backup_dir=/data/backup
   # 备份压缩打包目录
   gzip_dir=/data/backups/backups_zip
   # innobackupex 命令路径
   xtrabackup_bin=/opt/xtrabackup/bin/xtrabackup
   # 全量备信息名称 前缀
   full_backup_prefix=full
   # 增量备信息名称 前缀
   increment_prefix=incr
   # 错误日志文件(根据此文件知道备份是否成功)
   # format:
   # {week_day:1,dir:full/incr_2015-12-29_00-00-00_7,type:full/incr,date:2015-12-30}
   error_log=mysql_increment_hot_backup.err
   # 索引文件
   # format:
   # {week_day:1,dir:full/incr_2015-12-29_00-00-00_7,type:full/incr,date:2015-12-30}
   index_file=mysql_increment_hot_backup.index

5 恢复脚本

5.1 脚本

restore.sh


   #!/bin/bash
   # 获得程序路径名
   program_dir=`dirname $0`/..
   # 读取配置文件中的所有变量值, 设置为全局变量
   # 配置文件
   conf_file="$program_dir/conf/restore.conf"
   # MySQL 数据文件夹
   data_dir=`sed '/^data_dir=/!d;s/.*=//' $conf_file`
   # 备份索引文件路径
   backup_index_file=`sed '/^backup_index_file=/!d;s/.*=//' $conf_file`
   # percona-xtrabackup命令xtrabackup路径
   xtrabackup_bin=`sed '/^xtrabackup_bin=/!d;s/.*=//' $conf_file`
   # 备份文件目录
   backup_restore_dir=`sed '/^backup_restore_dir=/!d;s/.*=//' $conf_file`
   # 检查配置文件正确性
   function exam_conf_file() {
       # 判断每个变量是否在配置文件中有配置,没有则退出程序
       if [ ! -n "$data_dir" ]; then echo 'fail: configure file data_dir not set'; exit 2; fi
       if [ ! -n "$backup_index_file" ]; then echo 'fail: configure file backup_index_file not set'; exit 2; fi
       if [ ! -n "$xtrabackup_bin" ]; then echo 'fail: configure file xtrabackup_bin not set'; exit 2; fi
       if [ ! -n "$backup_restore_dir" ]; then echo 'fail: configure file backup_restore_dir not set'; exit 2; fi
   }
   # 检查备份文件是否是压缩格式
   function exam_backup_restore_file(){
       file_backup_restore_name_arr=`ls $backup_restore_dir`
       for file_name in $file_backup_restore_name_arr;do
           if [ "${file_name##*.}"x = "bz2"x ];then
               tar -jxf $backup_restore_dir/$file_name -C $backup_restore_dir
               rm -rf $backup_restore_dir/$file_name
           fi

done
   }
   # 检查 MySQL 是否停止
   function exam_mysql_is_stop(){
       if [ 0 -eq `ps -ef | grep mysql | grep -v grep | wc -l` ]; then
           echo "MySQL 服务已停止"
       else
           /etc/init.d/mysqld stop
           echo "正在停止 MySQL 服务"
           sleep 3
           echo "已停止 MySQL 服务"
       fi
   }
   # 检查 MySQL data 文件是否删除
   function exam_data_is_del(){
       if [ -d $data_dir ];then
           echo "正在删除 MySQL 的data文件"
           rm -rf $data_dir
       else
           echo "MySQL 的数据文件已删除 "
       fi
   }
   # 读取备份索引文件
   function read_backup_index() {
       cat $backup_index_file | awk '{print $2}' | awk -F: '{print $2}' | awk '{sub(/.$/,"")}1'
   }
   # 准备全备文件
   function ready_full(){
       full_file_name=`echo ${1} | awk '{print $1}'`
       $xtrabackup_bin/innobackupex \
           --apply-log \
           --redo-only \
           $backup_restore_dir/$full_file_name

echo "全备文件已准备好"
   }
   # 准备增备文件
   function ready_incr(){
       backup_index=$(read_backup_index)
       full_file_name=`echo $backup_index | awk '{print $1}'`
       for file_name in $backup_index;do
           if [ 1 -eq `echo "$file_name" | grep incr | wc -l` ]; then
               $xtrabackup_bin/innobackupex \
                   --apply-log \
                   --redo-only \
                   $backup_restore_dir/$full_file_name \
                   --incremental-dir=$backup_restore_dir/$file_name
           fi
       done
       echo "增备文件已准备好"
   }
   # 执行备份恢复
   function exec_backup_restore(){
       echo "开始进行备份恢复"
       full_file_name=`echo ${1} | awk '{print $1}' `
       $xtrabackup_bin/innobackupex \
           --copy-back \
           --datadir=$data_dir \
           $backup_restore_dir/$full_file_name
   }
   # 执行
   function main() {
       # 检查配置文件正确性
       exam_conf_file
       # 检查备份文件是否是压缩格式
       exam_backup_restore_file
       # 检查 MySQL 是否停止
       exam_mysql_is_stop
       # 检查 MySQL data 文件是否删除
       exam_data_is_del
       # 读取索引文件
       backup_index=$(read_backup_index)
       # 准备全备文件
       ready_full $backup_index
       # 准备增备文件
       ready_incr
       # 执行备份恢复
       exec_backup_restore $backup_index
       # 对数据文件进行赋权
       echo "重新对数据目录赋权"
       chown -R mysql:mysql $data_dir
       echo "正在启动MySQL"
       /etc/init.d/mysqld start
       echo "备份恢复成功"
   }
   main

5.2 配置文件

restore.conf


   # MySQL 数据文件夹
   data_dir=/opt/mysql/data
   #备份索引文件路径
   backup_index_file=/opt/xtrabackup/backup/var/mysql_increment_hot_backup.index
   #xtrabackup bin 的目录
   xtrabackup_bin=/opt/xtrabackup/bin
   # 备份文件目录
   backup_restore_dir=/data/backups/backups_zip

来源:https://www.cnblogs.com/FrostBoy/p/14885065.html

标签:MySQL,Xtrabackup,备份,恢复
0
投稿

猜你喜欢

  • php面向对象程序设计

    2023-05-29 15:55:45
  • 解决pycharm中导入自己写的.py函数出错问题

    2023-07-09 12:12:05
  • 如何有效防止sql注入的方法

    2024-01-18 21:18:13
  • 使用Python开发游戏运行脚本成功调用大漠插件

    2021-03-09 21:05:53
  • 拒绝盗图!教你怎么用python给图片加水印

    2022-05-29 21:42:51
  • Python的Django框架中forms表单类的使用方法详解

    2021-07-31 04:31:40
  • 比较不错的函数式JavaScript编程指南教程

    2023-08-25 08:24:41
  • python错误提示:Errno 2] No such file or directory的解决方法

    2022-03-30 10:46:26
  • Python获取Linux系统下的本机IP地址代码分享

    2021-07-23 00:26:22
  • 六种php加密解密方法实例讲解

    2023-07-01 12:16:02
  • Python实现发送邮件到自己邮箱

    2023-10-18 17:08:11
  • python反反爬虫技术限制连续请求时间处理

    2023-08-27 13:53:04
  • Python使用pyecharts控件绘制图表

    2023-11-08 17:59:54
  • js+html制作简单验证码

    2024-04-19 10:44:33
  • jquery AJAX 三个发送状态 posting, error, success

    2010-07-31 18:59:00
  • MySQL查看和修改时区的方法

    2024-01-15 05:42:33
  • python中如何利用matplotlib画多个并列的柱状图

    2022-04-14 12:38:42
  • python 利用jinja2模板生成html代码实例

    2023-11-19 18:56:41
  • Opencv图像处理之详解掩膜mask

    2022-08-12 23:40:44
  • 《色彩解答》系列之一 色彩层次

    2008-02-17 14:26:00
  • asp之家 网络编程 m.aspxhome.com