概述
本文档将详细介绍如何为Minio进行全量和增量备份,以及如何进行数据恢复。我们将使用rsync工具进行备份,并且会在每天定时进行全量备份以及每五分钟进行一次增量备份。还原数据时,可以选择特定日期的备份进行恢复,也可以选择是否还原增量备份数据。
备份策略
每天一次全量备份,五分钟一次增量备份
安装rsync
yum install -y rsync
目录结构说明
# 脚本所在目录
/usr/local/minio/bin
├── backup_env.sh
├── backup_full.sh
├── backup_incremental.sh
└── backup_restore.sh
# 备份文件所在目录
/mnt/backup/minio/data/
├── 2024-03-10_00-00-01.tar.gz
├── 2024-03-11_00-00-01.tar.gz
├── 2024-03-12_00-00-01.tar.gz
├── 2024-03-13_00-00-01.tar.gz
├── 2024-03-14_00-00-01.tar.gz
├── 2024-03-15_00-00-01.tar.gz
├── 2024-03-16_00-00-01.tar.gz
├── 2024-03-17_00-00-01.tar.gz
├── 2024-03-18_00-00-01.tar.gz
└── 2024-03-19_00-00-01
├── full
├── full_backup_success_flag
├── full.log
├── incremental
└── incremental.log
环境变量脚本
在备份和还原脚本中,这些配置变量会被引用,确保您替换脚本中的路径为您的实际值
vim backup_env.sh
#!/bin/bash
# Minio安装目录
MINIO_HOME="/usr/local/minio"
# 待备份目录
SOURCE_DIR="${MINIO_HOME}/data"
# 备份文件存储目录
BACKUP_DIR="/mnt/backup/minio/data"
# 备份数据保留天数
RETENTION_PERIOD=7
全量备份脚本
该脚本创建全量备份,清理过期备份。
vim backup_full.sh
#!/bin/bash
# 全量备份脚本
set -e
set -x
#获取当前脚本所在路径
CUR_PATH=$(cd `dirname $0`; pwd)
# 导入配置文件中的公共变量
source ${CUR_PATH}/backup_env.sh
# 定义备份目录及日志文件
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"
# 创建全量备份目录
if [ ! -d "$FULL_BACKUP_DIR" ]; then
mkdir -p "$FULL_BACKUP_DIR"
fi
# 全量备份并记录耗时到日志文件中
(time rsync -av --delete "$SOURCE_DIR" "$FULL_BACKUP_DIR") >"${FULL_LOG_FILE}" 2>&1
# 检查全量备份是否成功
if [ $? -eq 0 ]; then
touch ${DATE_BACKUP_DIR}/full_backup_success_flag
# 压缩其它全量备份文件
echo "压缩其它全量备份文件..." >>"${FULL_LOG_FILE}"
old_backup_file=$(find "$BACKUP_DIR" -maxdepth 1 -type d -not -name "$DATE_STR"|grep -v "$BACKUP_DIR"'$')
if [ -z "${old_backup_file}" ]; then
echo "暂无旧备份文件" >>"${FULL_LOG_FILE}"
else
echo "待处理旧备份文件:" >>"${FULL_LOG_FILE}"
echo "$old_backup_file" | xargs -I {} echo {} >>"${FULL_LOG_FILE}"
echo "压缩旧备份文件..." >>"${FULL_LOG_FILE}"
echo "$old_backup_file" | xargs -r -I {} sh -c 'tar -czf {}.tar.gz -C {} -P .'
echo "压缩成功!" >>"${FULL_LOG_FILE}"
echo "删除旧备份文件..." >>"${FULL_LOG_FILE}"
echo "$old_backup_file" | xargs -r -I {} rm -rf {}
echo "删除成功!" >>"${FULL_LOG_FILE}"
fi
echo "全量备份:${DATE_BACKUP_DIR},成功" >>"${FULL_LOG_FILE}"
else
echo "全量备份:${DATE_BACKUP_DIR},失败" >>"${FULL_LOG_FILE}"
fi
# 清理过期备份
find "$BACKUP_DIR" -ctime +$RETENTION_PERIOD -exec rm -rf {} \;
set +x
命令解析
(time rsync -av --delete "$SOURCE_DIR" "$FULL_BACKUP_DIR") >"${FULL_LOG_FILE}" 2>&1
该命令用于使用
rsync
工具进行数据同步,并将同步过程中的输出信息(包括标准输出和错误输出)重定向到指定的日志文件中。命令详细解释如下:
time
: 这是一个Unix/Linux命令,用于测量并显示命令执行所花费的时间。rsync
: 是一个强大的文件同步工具,用于在本地或远程之间进行数据备份或同步。av
: 这是rsync的选项组合,其中:
a
:归档模式,相当于rlptgoD
的组合,保留源文件的所有属性(如权限、时间戳、软硬链接等)并递归处理目录。v
:详细输出模式,会让rsync运行时显示详细的同步信息。-delete
:这是一个rsync选项,表示在目标目录中删除那些源目录不存在的文件和目录,使得目标目录与源目录保持一致。"$SOURCE_DIR"
和"$FULL_BACKUP_DIR"
:分别为源目录和目标目录,它们是变量引用,实际执行时会替换为具体的路径。> "${FULL_LOG_FILE}"
: 将命令的标准输出重定向到${FULL_LOG_FILE}
这个文件中,即同步过程中的详细信息会被记录在这个日志文件里。2>&1
:这是将标准错误输出重定向到标准输出的语法,也就是说,任何错误信息也会被写入到${FULL_LOG_FILE}
这个日志文件中。综上所述,此命令的作用是:通过rsync工具以归档模式递归地同步源目录至目标目录,同时删除目标目录中源目录没有的文件,并将整个同步过程(包括详细信息和错误信息)都记录到指定的日志文件中,并且还显示了整个操作的执行时间。
增量备份脚本
该脚本会基于最新的全量备份创建增量备份
vim backup_incremental.sh
#!/bin/bash
# 增量备份脚本
set -e
set -x
#获取当前脚本所在路径
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"
# 定义增量备份目录
DATE_STR="$(date '+%Y-%m-%d_%H-%M-%S')"
INCREMENTAL_BACKUP_DIR="${LATEST_BACKUP}/incremental/${DATE_STR}"
# 检查全量备份是否存在
if [ -f "${LATEST_BACKUP}/full_backup_success_flag" ]; then
# 创建增量备份目录
if [ ! -d "$INCREMENTAL_BACKUP_DIR" ]; then
mkdir -p "${INCREMENTAL_BACKUP_DIR}"
fi
echo "开始增量备份:${INCREMENTAL_BACKUP_DIR}" >>"${INCREMENTAL_LOG_FILE}"
# 增量备份并记录耗时到日志文件中
(time rsync -av --delete --link-dest="$LATEST_FULL_BACKUP" "$SOURCE_DIR" "$INCREMENTAL_BACKUP_DIR") >>"${INCREMENTAL_LOG_FILE}" 2>&1
# 检查增量备份是否成功
if [ $? -eq 0 ]; then
echo "增量备份:${INCREMENTAL_BACKUP_DIR},成功" >>"${INCREMENTAL_LOG_FILE}"
# 只保留最新的10个增量备份
#find "${LATEST_BACKUP}/incremental" -maxdepth 1 -type d -exec stat -c "%Y %n" {} \; | sort -n | grep -vE "\\${LATEST_BACKUP}/incremental\$" | head -n -1 | awk '{print $2}'| xargs rm -rf
prepare_delete_file=$(find "${LATEST_BACKUP}/incremental" -maxdepth 1 -type d -exec stat -c "%Y %n" {} \; | sort -n | grep -v "${LATEST_BACKUP}"'/incremental$' | head -n -$INCREMENTAL_RETENTION_COUNT | awk '{print $2}')
if [ -z "${prepare_delete_file}" ]; then
echo "暂无要删除的备份文件" >>"${INCREMENTAL_LOG_FILE}"
else
echo "待删除备份文件:" >>"${INCREMENTAL_LOG_FILE}"
echo "$prepare_delete_file" | xargs -I {} echo {} >>"${INCREMENTAL_LOG_FILE}"
echo "$prepare_delete_file" | xargs -r -I {} rm -rf {}
echo "删除成功!" >>"${INCREMENTAL_LOG_FILE}"
fi
else
echo "增量备份:${INCREMENTAL_BACKUP_DIR},失败" >>"${INCREMENTAL_LOG_FILE}"
fi
else
echo "未找到最新有效的全量备份"
exit 1
fi
echo -e "\n\n\n\n" >>"${INCREMENTAL_LOG_FILE}"
#set +x
命令解析
(time rsync -av --delete --link-dest="$LATEST_FULL_BACKUP" "$SOURCE_DIR" "$INCREMENTAL_BACKUP_DIR") >>"${INCREMENTAL_LOG_FILE}" 2>&1
该命令执行的是基于$LATEST_FULL_BACKUP
的增量备份操作,将$SOURCE_DIR
与上次全量备份差异部分同步至$INCREMENTAL_BACKUP_DIR
,并且将本次增量备份的详细操作信息及可能遇到的错误信息一并追加记录到${INCREMENTAL_LOG_FILE}
日志文件中,同时显示操作耗时。
-link-dest="$LATEST_FULL_BACKUP"
: 这个参数是rsync进行增量备份的关键选项,它指定了一个最近的完整备份目录。当rsync发现当前要备份的文件与$LATEST_FULL_BACKUP
目录下的文件相同时,不会重新复制文件,而是创建一个指向已有文件的硬链接,这样可以节省存储空间并提高备份速度。
数据还原脚本
用户可以选择还原特定日期的备份,并选择是否还原增量备份数据
vim backup_restore.sh
#!/bin/bash
# Minio 数据还原脚本
#set -e
#set -x
#获取当前脚本所在路径
CUR_PATH=$(cd `dirname $0`; pwd)
# 导入配置文件中的公共变量
source ${CUR_PATH}/backup_env.sh
echo "################################################## Minio数据还原 ##################################################"
# 列出可供还原备份数据
echo "可供还原的备份数据:"
AVAILABLE_BACKUPS=$(ls -1 -d "$BACKUP_DIR"/*| grep -v '_restore_temp$' | xargs -I {} basename {})
if [ -z "$AVAILABLE_BACKUPS" ]; then
echo "暂无备份数据。"
exit 1
fi
# 列出备份数据并允许用户选择
select BACKUP_FILE in $AVAILABLE_BACKUPS
do
if [ -n "$BACKUP_FILE" ]; then
echo "您选择了备份文件:$BACKUP_FILE"
break
else
echo "无效的选择。请重新选择。"
fi
done
SELECTED_BACKUP_FILE="$BACKUP_DIR/${BACKUP_FILE}"
# 解压备份文件(如果是压缩文件)或复制文件夹
if [[ "$SELECTED_BACKUP_FILE" == *.tar.gz ]]; then
# 创建还原临时文件夹
RESTORE_TEMP_FOLDER="${SELECTED_BACKUP_FILE}_restore_temp"
if [ ! -d "$RESTORE_TEMP_FOLDER" ]; then
rm -rf ${RESTORE_TEMP_FOLDER}
mkdir -p "${RESTORE_TEMP_FOLDER}"
fi
tar -xzvf "$SELECTED_BACKUP_FILE" -C "$RESTORE_TEMP_FOLDER"
SELECTED_BACKUP_FILE=$RESTORE_TEMP_FOLDER
fi
# 找到全量备份数据,根据指定日期进行数据还原
FULL_BACKUP_DIR="$BACKUP_DIR/$(basename "$SELECTED_BACKUP_FILE")/full/data"
if [ ! -d "$FULL_BACKUP_DIR" ]; then
echo "未找到全量备份数据。无法进行还原。"
exit 1
fi
echo "找到全量备份数据:$FULL_BACKUP_DIR"
# 创建恢复时原始数据备份目录
db_data_backup_dir=${MINIO_HOME}/bak_data/$(date '+%Y-%m-%d_%H-%M-%S')
if [ ! -d "$db_data_backup_dir" ]; then
mkdir -p "${db_data_backup_dir}"
fi
#备份原始数据
echo "备份原始数据..."
mv ${SOURCE_DIR} ${db_data_backup_dir}
echo "备份原始数据完成"
# 用户选择需要还原增量数据
AVAILABLE_INCREMENTAL_BASE_BACKUPS="$BACKUP_DIR/$(basename "$SELECTED_BACKUP_FILE")/incremental"
AVAILABLE_INCREMENTAL_BACKUPS=$(ls -1 -d "$AVAILABLE_INCREMENTAL_BASE_BACKUPS"/* | xargs -I {} basename {})
if [ -z "$AVAILABLE_INCREMENTAL_BACKUPS" ]; then
echo "暂无增量备份数据。"
exit 1
fi
echo "请选择增量备份数据:"
# 列出增量备份数据并允许用户选择
select INCREMENTAL_BACKUP_FILE in $AVAILABLE_INCREMENTAL_BACKUPS
do
if [ -n "$INCREMENTAL_BACKUP_FILE" ]; then
echo "您选择了增量备份文件:$INCREMENTAL_BACKUP_FILE"
break
else
echo "无效的选择。请重新选择。"
fi
done
# 根据用户选择的增量备份,进行数据还原
SELECTED_INCREMENTAL_BACKUP_FILE="$AVAILABLE_INCREMENTAL_BASE_BACKUPS/$INCREMENTAL_BACKUP_FILE"
if [ -d "$SELECTED_INCREMENTAL_BACKUP_FILE" ]; then
echo "找到增量备份数据:$SELECTED_INCREMENTAL_BACKUP_FILE"
echo "还原备份……"
# 在这里添加还原增量备份数据的 rsync 命令
rsync -av "$SELECTED_INCREMENTAL_BACKUP_FILE/data/" "$SOURCE_DIR/"
echo "还原完成"
else
echo "未找到增量备份数据,无法进行还原。"
exit 1
fi
#set +x
配置定时任务
crontab -e
# 每天执行全量备份任务,凌晨执行
0 0 * * * /usr/local/minio/bin/backup_full.sh
# 每五分钟执行增量备份任务
*/5 * * * * /usr/local/minio/bin/backup_incremental.sh