使用innobackupex进行mysql的差异备份还原和延迟复制

使用innobackupex进行mysql的差异备份还原和延迟复制

背景:
有同事执行update语句没有添加where条件,导致大量脏数据,需要将这张表恢复到前一天

数据库上有备份,每周一次完整备份,每天一次差异备份
恢复的整个过程就是将每天的差异备份合并到完整备份中,然后一起恢复到数据库中

一、全备相关的命令:
# innobackupex --defaults-file="/etc/my.cnf" --user=root -p'pass' --socket=/tmp/mysql.sock /opt
全备之后,去数据库操作,创建新的对象或插入数据
# 增量备份命令:
innobackupex --user=root --password=123  --incremental --incremental-basedir=/opt/cmsdb20191202/full_2019-11-28_01-03-01_4/ /opt/cmsdb20191202/incr_2019-11-29_01-03-01_5/

二、使用全量备份和几天的增量备份,恢复数据

使用备份脚本备份出来的数据库:

[root@/opt]# ll
total 20
drwxr-xr-x 37 apache users 4096 Dec  3 09:37 full_2019-11-28_01-03-01_4
drwxr-xr-x 33 apache users 4096 Nov 29 01:25 incr_2019-11-29_01-03-01_5
drwxr-xr-x 33 apache users 4096 Nov 30 01:22 incr_2019-11-30_01-03-01_6
drwxr-xr-x 33 apache users 4096 Dec  1 01:23 incr_2019-12-01_01-03-01_7
drwxr-xr-x 33 apache users 4096 Dec  2 01:23 incr_2019-12-02_01-03-01_1

准备工作:
移除mysql的数据文件夹 /data/mysql_data,关闭mysql服务(/etc/my.cnf 的配置最好和备份的源库保持一致)

1、预处理,进行事物检查
innobackupex --defaults-file="/etc/my.cnf" --user=root -p'' --socket=/tmp/mysql.sock --apply-log --use-memory=4G /opt/cmsdb20191202/full_2019-11-28_01-03-01_4/

2、合并第1/2/3/4个增量备份到完全备份里面:
innobackupex --user=root --password='' --apply-log-only --redo-only /opt/cmsdb20191202/full_2019-11-28_01-03-01_4/ --incremental-dir=/opt/cmsdb20191202/incr_2019-11-29_01-03-01_5/

innobackupex --user=root --password='' --apply-log-only --redo-only /opt/cmsdb20191202/full_2019-11-28_01-03-01_4/ --incremental-dir=/opt/cmsdb20191202/incr_2019-11-30_01-03-01_6/

innobackupex --user=root --password='' --apply-log-only --redo-only /opt/cmsdb20191202/full_2019-11-28_01-03-01_4/ --incremental-dir=/opt/cmsdb20191202/incr_2019-12-01_01-03-01_7/

innobackupex --user=root --password='' --apply-log-only --redo-only /opt/cmsdb20191202/full_2019-11-28_01-03-01_4/ --incremental-dir=/opt/cmsdb20191202/incr_2019-12-02_01-03-01_1/
3、完全恢复数据库:
innobackupex --defaults-file="/etc/my.cnf" --user=root --socket=/tmp/mysql.sock --copy-back /opt/cmsdb20191202/full_2019-11-28_01-03-01_4/


三、修改恢复的数据文件权限:
chown -R mysql.mysql /data/mysql_data
五、启动mysql服务,登录mysql,检查数据:
     service mysql start

 
官方文档给出的恢复步骤:
innobackupex --apply-log --redo-only BASE-DIR
innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR-1
innobackupex --apply-log BASE-DIR --incremental-dir=INCREMENTAL-DIR-2
innobackupex --apply-log BASE-DIR
innobackupex --copy-back BASE-DIR


三、做主从的延迟复制

# 为避免后续发送类似情况,再次恢复数据,直接把这台数据库作为主库的从库,并做1天的延迟复制,可以恢复一天以内的数据:

# 做主从复制
MySQL [(none)]> change master to master_host='192.168.11.53',master_user='rep',master_password='wsdb123',master_log_file='mysql-bin.000306',master_log_pos=138555997;
Query OK, 0 rows affected, 2 warnings (0.03 sec)

MySQL [(none)]> start slave;

 Last_IO_Error: Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; these ids must be different for replication to work (or the --replicate-same-server-id option must be used on slave but this does not always make sense; please check the manual before using it).

解决办法:

MySQL [(none)]> set global server_id=207; 
Query OK, 0 rows affected (0.06 sec)

MySQL [(none)]> show variables like '%server_uuid%';
+---------------+--------------------------------------+
| Variable_name | Value                                |
+---------------+--------------------------------------+
| server_uuid   | 5e7197c1-15b9-16ea-b9dc-0050568d373d |
+---------------+--------------------------------------+
1 row in set (0.00 sec)

MySQL [(none)]> show variables like 'server_id';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 207   |
+---------------+-------+
1 row in set (0.00 sec)


# 做延迟复制:
登陆到Slave数据库服务器
mysql>stop slave;
mysql>CHANGE MASTER TO MASTER_DELAY = 86400;

mysql>start slave;
mysql>show slave status \G;

四、数据库备份相关的脚本:


主从数据库服务器均安装xtrabackup工具
wget http://repo.percona.com/tools/yum/release/7/RPMS/x86_64/percona-xtrabackup-24-2.4.12-1.el7.x86_64.rpm

yum localinstall percona-xtrabackup-24-2.4.12-1.el7.x86_64.rpm -y


# 备份计划任务
########mysql backup cms_company,每周4进行全备份,每天定时增量备份,保留一周
03       01       *       *       *  /usr/local/worksh/xtrabackup_cron/bin/mysql_increment_hot_backup.sh


# 备份脚本

[root@newcms:~]# cat  /usr/local/worksh/xtrabackup_cron/bin/mysql_increment_hot_backup.sh
#!/usr/bin/env bash

# Program: MySQL 增量备份脚本 使用 percona xtrabackup
##进入程序目录
cd /usr/local/worksh/xtrabackup_cron/bin
# 读取配置文件中的所有变量值, 设置为全局变量
# 配置文件
conf_file="../conf/mysql_increment_hot_backup.conf"
# mysql 用户
user=`sed '/^user=/!d;s/.*=//' $conf_file`
# mysql 密码
#password=`sed '/^password=/!d;s/.*=//' $conf_file`
password="pass"


# mysql 备份目录
backup_dir=`sed '/^backup_dir=/!d;s/.*=//' $conf_file`
# percona-xtrabackup 备份软件路径
xtrabackup_dir=`sed '/^xtrabackup_dir=/!d;s/.*=//' $conf_file`
# 全备是在一周的第几天
full_backup_week_day=`sed '/^full_backup_week_day=/!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`
# mysql 配置文件
mysql_conf_file=`sed '/^mysql_conf_file=/!d;s/.*=//' $conf_file`
# 备份错误日志文件
error_log=`sed '/^error_log=/!d;s/.*=//' $conf_file`
# 备份索引文件
index_file=`sed '/^index_file=/!d;s/.*=//' $conf_file`

# 备份日期
backup_date=`date +%F`
# 备份日期
backup_time=`date +%H-%M-%S`
# 备份日期
backup_week_day=`date +%u`

# 设置备份线程数
backup_thread=4

# 创建相关目录
log_dir=../log
var_dir=../var
mkdir -p $backup_dir
mkdir -p $log_dir
mkdir -p $var_dir



# 全量备份
function full_backup() {
  backup_folder=${full_backup_prefix}_${backup_date}_${backup_time}_${backup_week_day}

  mkdir -p $backup_dir/$backup_folder
  $xtrabackup_dir/bin/innobackupex   --defaults-file=$mysql_conf_file --user=$user --password=$password --parallel=$backup_thread --no-timestamp  $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_dir/bin/innobackupex \
    --defaults-file=$mysql_conf_file \
    --user=$user \
    --password=$password \
    --no-timestamp \
    --incremental \
    $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 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() {
  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() {
  echo "tar $1 ok"
}

# 发送备份到远程
function send_backup_to_remote() {
  echo "send $1 remote ok"
}
 
# 判断是应该全备还是增量备份
# 0:full, 1:incr
function get_backup_type() {
  full_backup_week_day=`sed '/^full_backup_week_day=/!d;s/.*=//' $conf_file`
  backup_type=0
  if [ "$full_backup_week_day" -eq `date +%u` ]; then
    backup_type=0
  else
    backup_type=1
  fi
  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 "$full_backup_week_day" ]; then echo 'fail: configure file full_backup_week_day 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 "$mysql_conf_file" ]; then echo 'fail: configure file mysql_conf_file 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 run() {
  # 检测配置文件值
  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
        # # 发送索引文件到远程
        # send_index_file_to_remote
        # 清除之前的备份
        delete_before_backup
        # 清除索引文件
        purge_index_from_file
        # 添加索引, 索引记录了当前最新的备份
        append_index_to_file $full_backup_prefix
      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 [ 0 -eq "$backup_ok" ]; then
      # 增量备份成功
        # # 打包最新备份
        # tar_backup_file $increment_prefix
        # # 将tar备份发送到远程
        # send_backup_to_remote $increment_prefix
        # 添加索引, 索引记录了当前最新的备份
        append_index_to_file $increment_prefix
      else
      # 增量备份失败
        # 删除备份目录
        rm -rf ${backup_dir}/${full_backup_prefix}_${backup_date}_${backup_time}_${backup_week_day}
        # 记录错误日志
        logging_backup_err $increment_prefix
      fi
      ;;
  esac
}

run
chown -R apache.users /data/MySQL_Data_Backup

# 配置文件

[root@newcms:/usr/local/worksh/xtrabackup_cron]# cat conf/mysql_increment_hot_backup.conf 
# mysql 用户名
user=backuser

# mysql 密码
password="pass"

# 备份存放路径
backup_dir=/data/MySQL_Data_Backup

# percona-xtrabackup 备份软件路径
xtrabackup_dir=/usr

# 全备是在一周的第几天
full_backup_week_day=4

# 全量备信息名称 前缀
full_backup_prefix=full

# 增量备信息名称 前缀
increment_prefix=incr

# mysql配置文件
mysql_conf_file=/etc/my.cnf

# 错误日志文件(更具此文件知道备份是否成功)
# format:
# {week_day:1,dir:full/incr_2015-12-29_00-00-00_7,type:full/incr,date:2015-12-30}
error_log=../var/mysql_increment_hot_backup.err

# 索引文件
# format:
# {week_day:1,dir:full/incr_2015-12-29_00-00-00_7,type:full/incr}
index_file=../var/mysql_increment_hot_backup.index

猜你喜欢

转载自www.cnblogs.com/reblue520/p/11983261.html