【生产级Mysql数据库备份和恢复】基于XtraBackup,对Mysql数据库进行全量、增量备份和还原

概要

数据库备份是确保数据安全性和可用性的关键步骤之一。Percona XtraBackup是一个开源工具,用于高性能MySQL数据库备份和恢复。在本文中,我们将探讨如何使用XtraBackup来备份和恢复MySQL数据库,只需修改环境变量脚本中的参数便可直接使用。

备份策略:

  1. 本地备份:每天一次全量备份,五分钟一次增量备份
  2. 异地备份:在全量备份和增量备份完成后,将备份数据同步到另一台主机上面

安装XtraBackup

首先,您需要安装XtraBackup。您可以从Percona的官方网站下载适用于您的操作系统的XtraBackup软件包,并按照安装说明进行安装。

创建Mysql备份用户

CREATE USER 'xbackup'@'%' IDENTIFIED BY 'password';
GRANT RELOAD, PROCESS, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'xbackup'@'%';
flush privileges;

目录结构说明:

/app/backup/mysql/
.
├── bin
│   ├── backup_all.sh                        # 将数据库备份成sql的脚本,在数据恢复时调用
│   ├── backup_env.sh                        # 环境变量脚本
│   ├── xtrabackup_full.sh                   # 全量备份脚本
│   ├── xtrabackup_incremental.sh            # 增量备份脚本
│   └── xtrabackup_restore.sh                # 数据还原脚本
└── data                                     # 备份文件生成目录
    ├── 2023-09-15_00-00-01                  # 备份文件目录
    │	├── full                             # 全量备份文件目录
    │	├── full_backup_success_flag         # 全量备份成功标志,异地备份成功后,写入远程全量备份保存目录,供增量备份时从此文件中获取远程全量备份保存目录
    │	├── full.log                         # 全量备份日志
    │	├── incremental                      # 增量备份文件目录
    │	└── incremental.log                  # 增量备份日志
    ├── 2023-09-15_00-00-01_restore_temp     # 数据还原时生成的临时文件
    ├── all_backup-20230915-091642.sql       # 数据还原时backup_all.sh输出的备份文件
    └── db_data                              # 原数据库数据文件备份目录(数据还原时生成)

环境变量脚本(backup_env.sh)

在备份和还原脚本中,这些配置变量会被引用,确保您替换脚本中的路径和MySQL连接信息为您的实际值

#!/bin/bash

# 说明:这是配置文件,用于存储MySQL连接信息和备份相关的路径。
# 在备份和还原脚本中,这些配置变量会被引用。

# MySQL连接信息
mysql_host="127.0.0.1"
mysql_port="3306"
mysql_user="xbackup"
mysql_password="password"
mysql_datadir="/home/mysql/mysql/data"
# 本地备份目录
backup_dir="/app/backup/mysql/data"
# 远程备份连接信息
remote_backup_link="root@backup.file.server"
# 远程备份目录
remote_backup_dir="/mnt/backup/mysql/data"
# XtraBackup路径
xtrabackup_path="/usr/local/xtrabackup/bin"
# 注意:请将上述MySQL连接信息替换为您的实际信息,并设置合适的备份目录。

全量备份脚本:xtrabackup_full.sh

该脚本会创建全量备份,并同步备份数据到远程服务器,定期清理过期备份。

#!/bin/bash
#set -e
#set -x

# 说明:这是一个用于执行全量备份的脚本,使用Percona XtraBackup工具。
# 该脚本会创建全量备份并定期清理过期备份。

# 获取当前脚本所在路径
cur_path=$(cd `dirname $0`; pwd)
# 导入配置文件中的公共变量
source ${cur_path}/backup_env.sh

# 备份文件保存几天
day=30

# 定义全量备份目录
date_str="$(date '+%Y-%m-%d_%H-%M-%S')"
date_backup_dir="${backup_dir}/${date_str}"
full_backup_dir="${date_backup_dir}/full"
full_log_file="${date_backup_dir}/full.log"
incremental_backup_dir="${date_backup_dir}/incremental"

# 创建全量备份目录
if [ ! -d "$full_backup_dir" ]; then
	mkdir -p "${full_backup_dir}"
fi

# 使用Percona XtraBackup执行全量备份
${xtrabackup_path}/innobackupex ${full_backup_dir} --no-timestamp --host=$mysql_host --port=$mysql_port --user="${mysql_user}" --password="${mysql_password}" >"${full_log_file}" 2>&1

# 检查全量备份是否成功
if [ $? -eq 0 ]; then
	echo "全量备份成功" >>"${full_log_file}"
	# 全量备份成功,创建成功标志
	touch ${date_backup_dir}/full_backup_success_flag
	# 创建增量备份目录
	if [ ! -d "$incremental_backup_dir" ]; then
		mkdir -p "${incremental_backup_dir}"
	fi

	# 同步数据到备份盘
	echo "同步全量备份数据:${date_backup_dir}" >>"${full_log_file}"
	(time scp -r ${date_backup_dir} ${remote_backup_link}:${remote_backup_dir}) >>"${full_log_file}" 2>&1

	if [ $? -eq 0 ]; then
		echo "同步全量备份数据:${date_backup_dir},成功" >>"${full_log_file}"
		echo "${remote_backup_dir}/${date_str}" >>${date_backup_dir}/full_backup_success_flag
	else
		echo "同步全量备份数据:${date_backup_dir},失败" >>"${full_log_file}"
	fi
else
	# 全量备份失败,可以在此处添加错误处理逻辑
	# 重名失败的备份文件夹
	mv "$date_backup_dir" "${date_backup_dir}_error"
	echo "全量备份失败" >>"${full_log_file}"
	exit 1
fi

# 删除超过30天的备份
prepare_delete_file=$(find "${backup_dir}" -type d -mtime +$day)
if [ -z "${prepare_delete_file}" ]; then
	echo "暂无$day天前的备份文件" >>"${full_log_file}"
else
	find "${backup_dir}" -type d -mtime +$day -exec rm -rf {} \;
	echo "$day天前的备份文件清理完成:" >>"${full_log_file}"
	echo "${prepare_delete_file}" >>"${full_log_file}"
fi

#set +x

增量备份脚本:xtrabackup_incremental.sh

该脚本会基于最新的全量备份创建增量备份,并同步备份数据到远程服务器

#!/bin/bash
#set -e
#set -x
# 说明:这是一个用于执行增量备份的脚本,使用Percona XtraBackup工具。
# 该脚本会基于最新的全量备份创建增量备份,并同步备份数据到远程服务器。
# 获取当前脚本所在路径
cur_path=$(cd `dirname $0`; pwd)
# 导入配置文件中的公共变量
source ${cur_path}/backup_env.sh

# 获取全量备份的最新目录
latest_backup=$(find "${backup_dir}" -type f -name "full_backup_success_flag" -exec dirname {} \; | grep -v '_restore_temp$' | xargs ls -td | head -n 1)
latest_full_backup="${latest_backup}/full"
incremental_log_file="${latest_backup}/incremental.log"

# 检查全量备份是否存在
if [ -f "${latest_backup}/full_backup_success_flag" ]; then
	# 定义增量备份目录
	date_str="$(date '+%Y-%m-%d_%H-%M-%S')"
	incremental_backup_dir="${latest_backup}/incremental/${date_str}"

	# 创建增量备份目录
	if [ ! -d "$incremental_backup_dir" ]; then
		mkdir -p "${incremental_backup_dir}"
	fi

	echo "开始增量备份:${incremental_backup_dir}" >>"${incremental_log_file}"
	# 使用Percona XtraBackup执行增量备份,将增量备份保存到相应的目录
	${xtrabackup_path}/innobackupex --incremental --no-timestamp --incremental-basedir="${latest_full_backup}" ${incremental_backup_dir} --host=$mysql_host --port=$mysql_port --user="${mysql_user}" --password="${mysql_password}" >>"${incremental_log_file}" 2>&1

	# 获取远程备份目录
	cur_remote_backup_dir=$(cat "${latest_backup}/full_backup_success_flag")
	# 检查全量备份是否成功
	if [ $? -eq 0 ]; then
		echo "增量备份成功" >>"${incremental_log_file}"
		cur_remote_incremental_backup_dir="${cur_remote_backup_dir}/incremental/${date_str}"

		# 同步数据到备份盘
		echo "同步增量数据:${incremental_backup_dir}" >>"${incremental_log_file}"
		(time scp -r ${incremental_backup_dir} ${remote_backup_link}:${cur_remote_incremental_backup_dir}) >>"${incremental_log_file}" 2>&1

		if [ $? -eq 0 ]; then
			echo "同步增量数据:${incremental_backup_dir},成功" >>"${incremental_log_file}"
		else
			echo "同步增量数据:${incremental_backup_dir},失败" >>"${incremental_log_file}"			
		fi

	else
		# 全量备份失败,可以在此处添加错误处理逻辑
		echo "增量备份失败" >>"${incremental_log_file}"
	fi

	# 同步增量日志
	echo "同步增量日志:${incremental_log_file}" >>"${incremental_log_file}"
	(time scp "${incremental_log_file}" "${remote_backup_link}":"${cur_remote_backup_dir}/incremental.log") >>"${incremental_log_file}" 2>&1
	echo -e "\n\n\n\n" >>"${incremental_log_file}"
else
	# 如果没有最新的全量备份,记录错误或采取适当的操作
	echo "未找到最新有效的全量备份" >>"${incremental_log_file}"
fi

#set +x

数据还原脚本:xtrabackup_restore.sh

用户可以选择还原特定日期的备份,并选择是否还原增量备份数据

#!/bin/bash
#set -e
#set -x
# 说明:这是一个用于执行MySQL数据库数据还原的脚本,可以还原全量备份和增量备份数据。
# 用户可以选择还原特定日期的备份,并选择是否还原增量备份数据。

# 获取当前脚本所在路径
cur_path=$(cd `dirname $0`; pwd)
# 导入配置文件中的公共变量
source ${cur_path}/backup_env.sh

echo "################################################## Mysql数据还原 ##################################################"

# 列出可供还原的备份数据
available_backups=$(find "${backup_dir}" -maxdepth 1 -type d -name '[0-9]*' -exec basename {} \; | sort -r)

if [ -z "${available_backups}" ]; then
    echo "暂无备份数据"
    exit 1
fi

echo "请选择全量备份数据:"
for item in "${available_backups}"
do 
	trimmed_item=$(echo "$item" | sed 's/^ *//;s/ *$//')
	echo -e "\e[32m$trimmed_item\e[0m"
done

# 提示用户输入指定备份数据
read -p "请输入要还原的全量备份日期(格式:YYYY-MM-DD_HH-MM-SS): " selected_backup_date

selected_backup_dir=${backup_dir}/${selected_backup_date}
# 检查指定的备份是否存在
if [ ! -d "${selected_backup_dir}" ]; then
    echo "选择的备份不存在"
    exit 1
fi

# 复制备份文件,后续还原基于复制的备份文件这样不会破坏原始备份文件
copy_selected_backup_dir="${selected_backup_dir}_restore_temp"
if [ -d "${copy_selected_backup_dir}" ]; then
    rm -rf ${copy_selected_backup_dir}
fi

cp -r ${selected_backup_dir} ${copy_selected_backup_dir} 
selected_full_backup_dir=${copy_selected_backup_dir}/full
selected_incremental_backup_base_dir=${copy_selected_backup_dir}/incremental

# 提示用户是否需要还原增量备份数据
read -p "是否需要还原增量备份数据?(Y/N): " restore_incremental

if [ "${restore_incremental}" == "Y" ]; then
    # 列出可供还原的增量备份数据
	available_incremental_backups=$(find "${selected_incremental_backup_base_dir}" -maxdepth 1 -type d -name '[0-9]*' -exec basename {} \; | sort -r)
	
	if [ -z "${available_incremental_backups}" ]; then
        echo "暂无备份数据"
        exit 1
    fi
	
	echo "请选择增量备份数据:"
	for item in "${available_incremental_backups}"
	do 
		trimmed_item=$(echo "$item" | sed 's/^ *//;s/ *$//')
		echo -e "\e[32m$trimmed_item\e[0m"
	done
    
    # 需要还原增量数据
    read -p "请输入增量备份日期(格式:YYYY-MM-DD_HH-MM-SS): " incremental_backup_date

	selected_incremental_backup_dir=${selected_incremental_backup_base_dir}/${incremental_backup_date}
    # 检查指定的增量备份是否存在
    if [ ! -d "${selected_incremental_backup_dir}" ]; then
        echo "指定日期的增量备份不存在"
        exit 1
    fi

    # 使用 innobackupex 还原全量和增量备份数据
    innobackupex --apply-log --redo-only "${selected_full_backup_dir}"
    innobackupex --apply-log --redo-only --incremental-dir="${selected_incremental_backup_dir}" "${selected_full_backup_dir}"
	
elif [ "${restore_incremental}" == "N" ]; then
	# 不需要还原增量数据,只还原全量备份数据
	innobackupex --apply-log --redo-only "${selected_full_backup_dir}"    
else  
    echo "输入出错误!"
	exit 1
fi

# 备份原数据库数据sql脚本
bash ${cur_path}/backup_all.sh

# 停止Mysql服务器
systemctl stop mysqld.service

# 创建数据库数据文件的备份目录
db_data_backup_dir=${backup_dir}/db_data/$(date '+%Y-%m-%d_%H-%M-%S')
if [ ! -d "$db_data_backup_dir" ]; then
    mkdir -p "${db_data_backup_dir}"
fi

# 备份数据库数据文件
mv ${mysql_datadir} ${db_data_backup_dir}

# 恢复数据
innobackupex --copy-back ${selected_full_backup_dir}

# 授权恢复的数据文件
chown -R mysql:mysql ${mysql_datadir}

# 最后,您可以根据需要启动MySQL服务
systemctl start mysqld.service

echo "数据恢复成功!"

# 清空临时文件
if [ -d "${copy_selected_backup_dir}" ]; then
    rm -rf ${copy_selected_backup_dir}
fi

#set +x

备份和还原涉及到重要的数据库操作,请谨慎测试并确保在生产环境之前使用。

配置定时任务

crontab -e

# 每天执行全量备份任务,凌晨执行
0 0 * * * /app/backup/mysql/bin/xtrabackup_full.sh

# 每五分钟执行增量备份任务
*/5 * * * * /app/backup/mysql/bin/xtrabackup_incremental.sh
  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值