备份

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

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

全备

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

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

增备

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

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

备份恢复

准备数据

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

    innobackupex --apply-log --redo-only /backup/2021-06-01_14-44-54/
    # 将增量备份整合进全备份中
innobackupex --apply-log --redo-only /backup/2021-06-01_14-44-54/ --incremental-dir=/backup/2021-06-01_14-48-24

进行恢复

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

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

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

    chown -R mysql:mysql data/

到这恢复就完成了。

目录结构

备份脚本

脚本

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

如果同有安装expect 的需要安装一下,使用这个插件可以自动输入密码

expect_scp

    #!/usr/bin/expect -f
set timeout 10
set host [lindex $argv 0]
set username [lindex $argv 1]
set password [lindex $argv 2]
set src_file [lindex $argv 3]
set dest_file [lindex $argv 4]
set dest_prot [lindex $argv 5]
spawn scp -P $dest_prot $src_file $username@$host:$dest_file
expect {
"(yes/no)?"
{
send "yes\n"
expect "*assword:" { send "$password\n"}
}
"*assword:"
{
send "$password\n"
}
}
expect "100%"
expect eof

配置文件

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

恢复脚本

脚本

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

配置文件

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

细节决定成败!

个人愚见,如有不对,恳请扶正!

MySQL | 使用Xtrabackup进行备份和备份恢复的更多相关文章

  1. mysql innobackupex xtrabackup 大数据量 备份 还原

    大数据量备份与还原,始终是个难点.当MYSQL超10G,用mysqldump来导出就比较慢了.在这里推荐xtrabackup,这个工具比mysqldump要快很多. 一.Xtrabackup介绍 1, ...

  2. mysql innobackupex xtrabackup 大数据量 备份 还原(转)

    原文:http://blog.51yip.com/mysql/1650.html 作者:海底苍鹰 大数据量备份与还原,始终是个难点.当MYSQL超10G,用mysqldump来导出就比较慢了.在这里推 ...

  3. xtrabackup备份(MySQL备份)与恢复

    xtrabackup备份(MySQL备份)与恢复 1. innobackupex参数选项 --no-timestamp: 不创建一个时间戳 --defaults-file=[MY.CNF] //指定配 ...

  4. mysql之 xtrabackup原理、备份日志分析、备份信息获取

    一. xtrabackup备份恢复工作原理: extrabackup备份简要步骤 InnoDB引擎很大程度上与Oracle类似,使用redo,undo机制,XtraBackup在备份的时候,以read ...

  5. MySQL 采用Xtrabackup对数据库进行全库备份

    1,xtrabackup简介 关于数据库备份以及备份工具,参考:http://blog.itpub.net/26230597/viewspace-1460065/,这里来介绍xtrabackup已经如 ...

  6. MySQL 利用xtrabackup进行增量备份详细过程汇总 (转)

    Xtrabackup下载.安装以及全量备份请参考:http://blog.itpub.net/26230597/viewspace-1465772/ 1,创建mysql备份用户 mysql -uroo ...

  7. 【MySQL】全量+增量的备份/恢复

    生产环境中,有时需要做MySQL的备份和恢复工作.因MySQL是在运行过程中的,做全量备份需要时间,全量备份完成后又有数据变动,此时需要增量备份辅助.如果想恢复数据到一个空库(例如数据迁移或者上云等更 ...

  8. xtrabackup之Innobackupex增量备份及恢复

    演示增量备份 #启动一个全备 innobackupex \ > --defaults-/my.cnf \ > --host=127.0.0.1 \ > --user=xtrabk \ ...

  9. mysql 数据表备份导出,恢复导入操作实践

    因为经常跑脚本的关系, 每次跑完数据之后,相关的测试服数据库表的数据都被跑乱了,重新跑脚本恢复回来速度也不快,所以尝试在跑脚本之前直接备份该表,然后跑完数据之后恢复的方式,应该会方便一点.所以实践一波 ...

随机推荐

  1. 3D网页小实验-基于Babylon.js与recast.js实现RTS式单位控制

    一.运行效果 1.建立一幅具有地形起伏和不同地貌纹理的地图: 地图中间为凹陷的河道,两角为突出的高地,高地和低地之间以斜坡通道相连. 水下为沙土材质,沙土材质网格贴合地形,河流材质网格则保持水平. 2 ...

  2. 如何在 Docker 环境下自动给 .NET 程序生成 Dump

    前言 之前"一线码农"大佬有写文章介绍了如何在 windows 下自动 dump,正好手里有个在 docker 环境下 dump 的需求,所以在参考大佬文章的基础上,有了本篇. ​ ...

  3. 鸿蒙 Android iOS 应用开发对比02

    个人理解,不抬杠 转载请注明原著:博客园老钟 https://www.cnblogs.com/littlecarry/ IOS 把界面抽象成 "控制" Controller:And ...

  4. 游刃于私有网络与公共网络之间的NAT

    网络地址转化技术NAT 1. 应用场景 2. NAT 2.1 静态NAT 2.2 动态NAT 2.3 NAPT 2.4 EASY IP 3. NAT配置 3.1 静态NAT 3.2 动态NAT 3.3 ...

  5. 服务器ip迁移纪要

    21楼机房之前已配25网段静态ip,机架上14台服务器接22楼机房交换机,同样25网段. 实际有两种情况, a.25网段ip没有被他人占用,这种情况无需更改ip. b.该IP已被外部使用,ip冲突,无 ...

  6. TaskManager任务管理工具类

    TaskManager任务管理工具类 public class TaskManager { public static AbstractTask newTask(TaskContext taskIns ...

  7. AICompiler动态shape编译框架

    AICompiler动态shape编译框架 移动互联网的兴起,不仅产生了海量数据,也对人机交互有了新的定义.企业如何动态处理不同规格图片数据,如何更灵活处理不同长度的对话语料等等,提升企业运营效率,争 ...

  8. 循环IRNNv2Layer实现

    循环IRNNv2Layer实现 IRNNv2Layer实现循环层,例如循环神经网络(RNN),门控循环单元(GRU)和长期短期记忆(LSTM).支持的类型为RNN,GRU和LSTM.它执行循环操作,该 ...

  9. Ryzen 4000'Vermeer' CPU和Radeon RX'Big Navi'图形卡

    Ryzen 4000'Vermeer' CPU和Radeon RX'Big Navi'图形卡 来自中国媒体的多篇报道表明,AMD都准备在2020年第四季度初推出其下一代Ryzen 4000'Zen 3 ...

  10. Tomcat配置probe详细过程(步骤加截图)

    1.先下载probe.war包,点击probe.war进行下载:附上下载地址:https://github.com/psi-probe/psi-probe/releases 2.将probe.war包 ...