MySQL | 使用Xtrabackup进行备份和备份恢复
备份
进行备份前需要先创建备份用户,直接使用 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进行备份和备份恢复的更多相关文章
- mysql innobackupex xtrabackup 大数据量 备份 还原
大数据量备份与还原,始终是个难点.当MYSQL超10G,用mysqldump来导出就比较慢了.在这里推荐xtrabackup,这个工具比mysqldump要快很多. 一.Xtrabackup介绍 1, ...
- mysql innobackupex xtrabackup 大数据量 备份 还原(转)
原文:http://blog.51yip.com/mysql/1650.html 作者:海底苍鹰 大数据量备份与还原,始终是个难点.当MYSQL超10G,用mysqldump来导出就比较慢了.在这里推 ...
- xtrabackup备份(MySQL备份)与恢复
xtrabackup备份(MySQL备份)与恢复 1. innobackupex参数选项 --no-timestamp: 不创建一个时间戳 --defaults-file=[MY.CNF] //指定配 ...
- mysql之 xtrabackup原理、备份日志分析、备份信息获取
一. xtrabackup备份恢复工作原理: extrabackup备份简要步骤 InnoDB引擎很大程度上与Oracle类似,使用redo,undo机制,XtraBackup在备份的时候,以read ...
- MySQL 采用Xtrabackup对数据库进行全库备份
1,xtrabackup简介 关于数据库备份以及备份工具,参考:http://blog.itpub.net/26230597/viewspace-1460065/,这里来介绍xtrabackup已经如 ...
- MySQL 利用xtrabackup进行增量备份详细过程汇总 (转)
Xtrabackup下载.安装以及全量备份请参考:http://blog.itpub.net/26230597/viewspace-1465772/ 1,创建mysql备份用户 mysql -uroo ...
- 【MySQL】全量+增量的备份/恢复
生产环境中,有时需要做MySQL的备份和恢复工作.因MySQL是在运行过程中的,做全量备份需要时间,全量备份完成后又有数据变动,此时需要增量备份辅助.如果想恢复数据到一个空库(例如数据迁移或者上云等更 ...
- xtrabackup之Innobackupex增量备份及恢复
演示增量备份 #启动一个全备 innobackupex \ > --defaults-/my.cnf \ > --host=127.0.0.1 \ > --user=xtrabk \ ...
- mysql 数据表备份导出,恢复导入操作实践
因为经常跑脚本的关系, 每次跑完数据之后,相关的测试服数据库表的数据都被跑乱了,重新跑脚本恢复回来速度也不快,所以尝试在跑脚本之前直接备份该表,然后跑完数据之后恢复的方式,应该会方便一点.所以实践一波 ...
随机推荐
- Go语言web开发---Beego的session
一.简介 Session是一段保存在服务器上的信息,当客户端第一次访问服务器时创建Session,同时也会创建一个名为beegosessionID,值为创建的Session的id的Cookie. 这个 ...
- GO语言面向对象07---面向对象练习02
package main import "fmt" /* ·定义接口IPerson,定义吃喝睡三个抽象方法: ·定义一个IPerson的实现类Person,实现吃喝睡方法; ·定义 ...
- Go语言的函数07---闭包练习(ATM存取款)
package main import "fmt" /* @ATM(闭包练习) ·写一个Atm(函数),返回存款,取款两个内层函数 ·存款,取款两个函数,都以一个金额为参数,返回存 ...
- 开源项目核心商城(CoreShop)
帮小伙伴推一下他的开源项目作者是@大灰灰 核心商城(CoreShop)Beta 支持可视化布局的.Net小程序商城 [![star](https://gitee.com/CoreUnion/CoreS ...
- VUE3后台管理系统【路由鉴权】
前言: 在"VUE3后台管理系统[模板构建]"文章中,详细的介绍了我使用vue3.0和vite2.0构建的后台管理系统,虽然只是简单的一个后台管理系统,其中涉及的技术基本都覆盖了, ...
- Python小白的数学建模课-A3.12 个新冠疫情数模竞赛赛题与点评
新冠疫情深刻和全面地影响着社会和生活,已经成为数学建模竞赛的背景帝. 本文收集了与新冠疫情相关的的数学建模竞赛赛题,供大家参考,欢迎收藏关注. 『Python小白的数学建模课 @ Youcans』带你 ...
- 目标检测coco数据集点滴介绍
目标检测coco数据集点滴介绍 1. COCO数据集介绍 MS COCO 是google 开源的大型数据集, 分为目标检测.分割.关键点检测三大任务, 数据集主要由图片和json 标签文件组成. c ...
- TOF摄像机可以替代Flash激光雷达吗?
TOF摄像机可以替代Flash激光雷达吗? 一.基于ToF技术的Flash激光雷达 基本成像原理上ToF Camera与LiDAR相同,都采用飞行时间测距技术(包括利用APD或SPAD的直接测距法,和 ...
- 嵌入式C程序基础与编程结构
嵌入式C程序基础与编程结构 Basics of Embedded C Program and Programming Structure 嵌入式C编程是处理器在我们日常生活中遇到的每一个嵌入式系统(如 ...
- Django(56)Mixins工具集的使用
前言 mixins翻译成中文是混入,组件的意思.在DRF中,针对获取列表,检索,创建等操作,都有相应的mixin,一般我们自定义创建的类视图都会继承自GenericAPIView和Mixins一起使用 ...