背景介绍
本数据库备份脚本基于 ToB 生产项目,单机服务架构,仅用于防止误删数据库而生
软件版本
- 系统版本:CentOS Linux release 7.9.2009 (Core)
- Kubernetes 版本:v1.19.16
- Mysql 版本:v8.0.34
运行脚本前置工作
# 环境变量赋值或编辑 profile 永久加入环境变量
export MYSQL_ROOT_PASSWORD=xxxxx
数据库备份脚本详情
#!/bin/bash
#*************************************************************************************************************
#Author: kubecc
#Date: 2024-11-08
#FileName: mysqlbackpu.sh
#blog: www.kubecc.com
#Description: product databases backup
#Copyright (C): 2024 All rights reserved
#*************************************************************************************************************
# 定义变量
NAMESPACE="devops-tools"
POD_NAME=$(kubectl get pods -n ${NAMESPACE} | grep mysql | awk '{print $1}')
DB_USER="root"
DB_PASSWORD="${MYSQL_ROOT_PASSWORD}" # 环境变量获取
BACKUP_DIR="/data/backup/mysql" # 备份文件存放路径
BACKUP_SUCCESS=true # 标志变量,用于跟踪备份是否成功
LOG_FILE="${BACKUP_DIR}/backup.log" # 日志文件路径
# 创建备份目录(如果不存在)
mkdir -p ${BACKUP_DIR}
# 将标准输出和标准错误重定向到日志文件
exec > >(tee -a ${LOG_FILE}) 2>&1
echo "===== 备份开始时间: $(date) ====="
# 获取所有数据库名称(排除系统数据库)
DATABASES=$(kubectl exec "${POD_NAME}" -n "${NAMESPACE}" -- mysql -u"${DB_USER}" -p"${DB_PASSWORD}" -e "SHOW DATABASES;" | grep -Ev "(Database|information_schema|performance_schema|mysql|sys)")
# 检查是否获取到数据库
if [ -z "$DATABASES" ]; then
echo "未找到可备份的数据库。"
exit 1
fi
# 遍历每个数据库并备份
for DB_NAME in ${DATABASES}; do
BACKUP_FILE="${BACKUP_DIR}/${DB_NAME}_$(date +%Y%m%d%H%M%S).sql"
BACKUP_FILE_GZ="${BACKUP_FILE}.gz" # 压缩后的文件名
echo "正在备份数据库: ${DB_NAME}..."
# 使用kubectl exec在MySQL Pod中执行备份命令,并加上--single-transaction
if kubectl exec "${POD_NAME}" -n "${NAMESPACE}" -- mysqldump -u"${DB_USER}" -p"${DB_PASSWORD}" --single-transaction "${DB_NAME}" >"${BACKUP_FILE}"; then
echo "数据库 ${DB_NAME} 备份成功,备份文件保存在: ${BACKUP_FILE}"
# 压缩备份文件
echo "正在压缩备份文件: ${BACKUP_FILE}..."
if gzip "${BACKUP_FILE}"; then
echo "备份文件压缩成功,压缩文件保存在: ${BACKUP_FILE_GZ}"
# 删除原始 SQL 文件
rm -f "${BACKUP_FILE}"
echo "已删除原始 SQL 文件: ${BACKUP_FILE}"
else
echo "备份文件压缩失败,请检查错误信息。"
BACKUP_SUCCESS=false # 标记备份失败
fi
else
echo "数据库 ${DB_NAME} 备份失败,请检查错误信息。"
rm -f "${BACKUP_FILE}" # 删除可能不完整的备份文件
BACKUP_SUCCESS=false # 标记备份失败
fi
done
# 如果备份全部成功,则执行清理策略
if $BACKUP_SUCCESS; then
echo "所有数据库备份成功,正在检查是否需要清理超过 7 天的备份文件..."
# 查找匹配的文件
FILES_TO_DELETE=$(find "${BACKUP_DIR}" -name "*.gz" -mtime +7)
# 检查是否有需要删除的文件
if [ -z "$FILES_TO_DELETE" ]; then
echo "数据库备份完成,没有需要清理的数据。"
else
echo "找到的备份文件:"
echo "$FILES_TO_DELETE"
# 删除超过 7 天的备份文件,并列出删除的文件名称
echo "正在删除以下文件:"
# 检查清理是否完成
if find "${BACKUP_DIR}" -name "*.gz" -mtime +7 -exec echo "删除文件: {}" \; -exec rm -f {} \;; then
echo "备份文件清理完成,已删除超过 7 天的备份文件。"
else
echo "备份文件清理失败,请检查错误信息。"
fi
fi
else
echo "备份过程中出现失败,跳过清理策略。"
fi
echo "===== 备份结束时间: $(date) ====="
创建定时任务
运行脚本
每天凌晨 3:00 分开始备份,并清理7天之前的备份数据,
因为数据量不大,为了省事,所以每次都是全备,并将日志打印到指定文件中,
[root@master01 ~]# crontab -e
00 03 * * * bash /usr/local/sbin/mysqlbackup.sh
运行结果输出样例
[root@master01 ~]# bash mysqlbackup.sh
===== 备份开始时间: Fri Jan 10 15:32:07 CST 2025 =====
mysql: [Warning] Using a password on the command line interface can be insecure.
正在备份数据库: nacos_db...
mysqldump: [Warning] Using a password on the command line interface can be insecure.
数据库 nacos_db 备份成功,备份文件保存在: /data/backup/mysql/nacos_db_20250110153207.sql
正在压缩备份文件: /data/backup/mysql/nacos_db_20250110153207.sql...
备份文件压缩成功,压缩文件保存在: /data/backup/mysql/nacos_db_20250110153207.sql.gz
已删除原始 SQL 文件: /data/backup/mysql/nacos_db_20250110153207.sql
所有数据库备份成功,正在检查是否需要清理超过 7 天的备份文件...
找到的备份文件:
/data/backup/mysql/nacos_db_20250110140229.sql.gz
/data/backup/mysql/nacos_db_20240110140229.sql.gz
/data/backup/mysql/nacos_db_20230110140229.sql.gz
正在删除以下文件:
删除文件: /data/backup/mysql/nacos_db_20250110140229.sql.gz
删除文件: /data/backup/mysql/nacos_db_20240110140229.sql.gz
删除文件: /data/backup/mysql/nacos_db_20230110140229.sql.gz
备份文件清理完成,已删除超过 7 天的备份文件。
===== 备份结束时间: Fri Jan 10 15:32:07 CST 2025 =====
数据库恢复脚本详情
#!/bin/bash
#*************************************************************************************************************
#Author: kubecc
#Date: 2024-11-08
#FileName: mysqlrestore.sh
#blog:
#Description: product databases restore
#Copyright (C): 2024 All rights reserved
#*************************************************************************************************************
# 定义变量
NAMESPACE="devops-tools"
POD_NAME=$(kubectl get pods -n "${NAMESPACE}" | grep mysql | awk '{print $1}' ) # 获取 Pod 名称
DB_USER="root"
DB_PASSWORD="${MYSQL_ROOT_PASSWORD}" # 从环境变量获取密码
BACKUP_DIR="/data/backup/mysql" # 备份文件存储路径
# 函数:从备份文件名中解析数据库名称
get_databases_from_backups() {
ls "${BACKUP_DIR}" | grep -v backup.log |grep -v '*.sql.gz' | awk -F '_[0-9].' '{print $1}' | uniq | sort -r
}
# 函数:显示菜单并获取用户选择
show_menu() {
# 获取可恢复的数据库列表
DATABASES=$(get_databases_from_backups)
# 检查是否有可用的数据库备份文件
if [ -z "${DATABASES}" ]; then
echo "错误:没有可用的备份数据库。"
exit 1
fi
echo "请选择要恢复的数据库:"
select DB_NAME in ${DATABASES}; do
if [ -n "${DB_NAME}" ]; then
echo "你选择的数据库是: ${DB_NAME}"
break
else
echo "无效的选择,请重新选择。"
fi
done
}
# 函数:显示备份版本并获取用户选择
show_versions() {
# 获取匹配的备份文件列表
BACKUP_FILES=$(find "${BACKUP_DIR}" -name "${DB_NAME}_*.sql.gz" -printf '%f\n' | sort -r)
echo "请选择要恢复的备份版本:"
select BACKUP_FILE in ${BACKUP_FILES}; do
if [ -n "${BACKUP_FILE}" ]; then
echo "你选择的备份文件是: ${BACKUP_FILE}"
break
else
echo "无效的选择,请重新选择。"
fi
done
}
# 函数:恢复数据库
restore_database() {
local BACKUP_FILE=$1
local TARGET_DB=$2
# 解压备份文件
echo "正在解压备份文件..."
UNZIPPED_FILE="${BACKUP_FILE%.gz}"
gzip -c -d "${BACKUP_DIR}/${BACKUP_FILE}" > "${BACKUP_DIR}/${UNZIPPED_FILE}" || { echo "解压失败"; exit 1; }
# 将备份文件复制到 MySQL Pod
echo "正在将备份文件复制到 MySQL Pod..."
kubectl cp "${BACKUP_DIR}/${UNZIPPED_FILE}" "${POD_NAME}:/tmp/backup.sql" -n "${NAMESPACE}" || { echo "复制失败"; exit 1; }
# 进入 MySQL Pod 并恢复数据库
echo "正在恢复数据库..."
kubectl exec "${POD_NAME}" -n "${NAMESPACE}" -- bash -c '
mysql -u'"${DB_USER}"' -p'"${DB_PASSWORD}"' -e "DROP DATABASE IF EXISTS '"${TARGET_DB}"';"
mysql -u'"${DB_USER}"' -p'"${DB_PASSWORD}"' -e "CREATE DATABASE '"${TARGET_DB}"';"
mysql -u'"${DB_USER}"' -p'"${DB_PASSWORD}"' '"${TARGET_DB}"' < /tmp/backup.sql
rm /tmp/backup.sql
' || { echo "恢复失败"; exit 1; }
echo "数据库恢复完成!"
}
# 主函数
main() {
# 第一阶段:选择数据库
show_menu
# 第二阶段:选择备份版本
show_versions
# 第三阶段:恢复数据库
restore_database "${BACKUP_FILE}" "${DB_NAME}"
}
# 执行主函数
main
恢复演示
[root@master01 mysql]# bash /root/restore_mysql.sh
请选择要恢复的数据库:
1) sxxxx_asda122333_asd222 4) nacos
2) sads_sdasD 5) asd_asda_ax
3) nacos_db
#? 4
你选择的数据库是: nacos
请选择要恢复的备份版本:
1) nacos_20250110164213.sql.gz 3) nacos_20250110164203.sql.gz
2) nacos_20250110164205.sql.gz
#? 1
你选择的备份文件是: nacos_20250110164213.sql.gz
正在解压备份文件...
正在将备份文件复制到 MySQL Pod...
正在恢复数据库...
mysql: [Warning] Using a password on the command line interface can be insecure.
mysql: [Warning] Using a password on the command line interface can be insecure.
mysql: [Warning] Using a password on the command line interface can be insecure.
数据库恢复完成!
总结
这是一个初步实现的版本,功能已经完成,可以正常运行,但可能还需要进一步优化。
版权声明:「自由转载-保持署名-非商业性使用-禁止演绎 3.0 国际」(CC BY-NC-ND 3.0)
用一杯咖啡支持我们,我们的每一篇[文档]都经过实际操作和精心打磨,而不是简单地从网上复制粘贴。期间投入了大量心血,只为能够真正帮助到您。
暂无评论