感兴趣可以看看使用xtrabackup 备份与恢复MySQL数据完整操作过程
一、核心概念说明
- 全量备份:完整备份整个数据库的所有数据,是增量备份的基础,恢复时需优先使用。
- 增量备份:仅备份自上一次全量或增量备份后变化的数据,能节省存储空间和备份时间。
- 备份准备(prepare):备份文件生成后需执行此操作,用于整合数据、确保数据一致性,为恢复做准备。
二、全量备份操作
1. 备份命令
xtrabackup --user=数据库用户名 --password=数据库密码 --backup --target-dir=/备份存储路径/全量备份文件夹
2. 参数详解
--user:连接 MySQL 数据库的用户名,需具备备份权限(如 SELECT、LOCK TABLES 等)。--password:对应数据库用户的密码,若密码为空可省略此参数。--backup:指定执行备份操作。--target-dir:指定全量备份文件的存储路径,需确保路径存在且有写入权限。
3. 备份后准备
备份完成后必须执行准备命令,否则备份文件无法用于恢复:
xtrabackup --prepare --target-dir=/备份存储路径/全量备份文件夹
三、增量备份操作
1. 第一次增量备份(基于全量备份)
xtrabackup --user=数据库用户名 --password=数据库密码 --backup --target-dir=/备份存储路径/第一次增量备份文件夹 --incremental-basedir=/备份存储路径/全量备份文件夹
2. 后续增量备份(基于前一次增量备份)
xtrabackup --user=数据库用户名 --password=数据库密码 --backup --target-dir=/备份存储路径/第二次增量备份文件夹 --incremental-basedir=/备份存储路径/第一次增量备份文件夹
3. 参数详解
--incremental-basedir:指定增量备份的基准路径,第一次增量以全量备份路径为基准,后续增量以上一次增量备份路径为基准。


四、恢复操作(全量 + 增量)
1. 准备全量备份
xtrabackup --prepare --apply-log-only --target-dir=/备份存储路径/全量备份文件夹
--apply-log-only:仅应用日志,避免全量备份数据被修改,确保增量数据可叠加。
2. 合并第一次增量备份到全量备份
xtrabackup --prepare --apply-log-only --target-dir=/备份存储路径/全量备份文件夹 --incremental-dir=/备份存储路径/第一次增量备份文件夹
3. 合并后续增量备份(若有)
xtrabackup --prepare --target-dir=/备份存储路径/全量备份文件夹 --incremental-dir=/备份存储路径/第二次增量备份文件夹
- 注意:最后一次合并增量备份时,需移除
--apply-log-only参数,完成数据最终整合。
4. 停止 MySQL 服务
恢复前必须停止数据库服务,避免数据写入冲突:
systemctl stop mysqld
5. 清空 MySQL 数据目录
确保数据目录为空,避免旧数据干扰:
rm -rf /var/lib/mysql/* # 注意:此路径为默认MySQL数据目录,需根据实际情况修改
6. 执行恢复
xtrabackup --copy-back --target-dir=/备份存储路径/全量备份文件夹
--copy-back:将准备好的备份文件复制到 MySQL 数据目录。
7. 调整数据目录权限
恢复后需修改数据目录权限,确保 MySQL 服务可访问:
chown -R mysql:mysql /var/lib/mysql # 同样需匹配实际数据目录路径
8. 启动 MySQL 服务
systemctl start mysqld
五、注意事项
- 备份和恢复过程中,确保 MySQL 服务状态符合操作要求(备份时可正常运行,恢复时必须停止)。
- 备份路径和数据目录需有足够存储空间,增量备份需按顺序合并,不可跳过中间步骤。
- 操作前建议测试备份文件的可用性,避免因备份文件损坏导致恢复失败。
六、xtrabackup 全量与增量备份脚本
- 脚本包含全量备份和增量备份功能,支持自动创建备份目录、记录备份日志、清理指定天数前的旧备份。
- 需根据实际环境修改脚本开头的 “配置参数”,如数据库用户名、密码、备份路径等。
- 建议通过 Linux 的 crontab 定时任务执行,实现自动化备份(示例见脚本末尾)。
#!/bin/bash
# 配置参数(根据实际环境修改)
DB_USER="root" # 数据库用户名
DB_PASS="your_db_password" # 数据库密码
BACKUP_BASE_DIR="/data/mysql_backup" # 备份根目录
FULL_BACKUP_DIR="${BACKUP_BASE_DIR}/full" # 全量备份目录
INC_BACKUP_DIR="${BACKUP_BASE_DIR}/incremental" # 增量备份目录
LOG_FILE="${BACKUP_BASE_DIR}/backup.log" # 备份日志文件
RETENTION_DAYS=7 # 备份文件保留天数(超过自动删除)
MYSQL_DATA_DIR="/var/lib/mysql" # MySQL数据目录(默认路径,需确认)# 日志输出函数
log() {echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" >> "${LOG_FILE}"
}# 检查xtrabackup是否安装
if ! command -v xtrabackup &> /dev/null; thenlog "错误:未安装xtrabackup工具,请先安装后再执行脚本"exit 1
fi# 创建备份目录(若不存在)
mkdir -p "${FULL_BACKUP_DIR}" "${INC_BACKUP_DIR}" || {log "错误:创建备份目录失败"exit 1
}# 清理过期备份
clean_old_backups() {log "开始清理${RETENTION_DAYS}天前的旧备份"find "${BACKUP_BASE_DIR}" -type d -mtime +${RETENTION_DAYS} -exec rm -rf {} \; || {log "警告:清理旧备份时出现错误"}log "旧备份清理完成"
}# 全量备份函数
full_backup() {local backup_time=$(date +'%Y%m%d_%H%M%S')local full_backup_path="${FULL_BACKUP_DIR}/full_${backup_time}"log "开始执行全量备份,备份路径:${full_backup_path}"# 执行全量备份xtrabackup --user="${DB_USER}" --password="${DB_PASS}" --backup --target-dir="${full_backup_path}" &>> "${LOG_FILE}"if [ $? -eq 0 ]; thenlog "全量备份完成,开始准备备份文件"# 准备全量备份(用于恢复)xtrabackup --prepare --target-dir="${full_backup_path}" &>> "${LOG_FILE}"if [ $? -eq 0 ]; thenlog "全量备份准备完成"# 记录最新全量备份路径(供增量备份使用)echo "${full_backup_path}" > "${BACKUP_BASE_DIR}/latest_full_backup.txt"elselog "错误:全量备份准备失败"rm -rf "${full_backup_path}"exit 1fielselog "错误:全量备份执行失败"rm -rf "${full_backup_path}"exit 1fi
}# 增量备份函数
incremental_backup() {# 检查是否存在最新全量备份记录if [ ! -f "${BACKUP_BASE_DIR}/latest_full_backup.txt" ]; thenlog "错误:未找到全量备份记录,请先执行全量备份"exit 1filocal latest_full=$(cat "${BACKUP_BASE_DIR}/latest_full_backup.txt")# 检查全量备份目录是否存在if [ ! -d "${latest_full}" ]; thenlog "错误:最新全量备份目录${latest_full}不存在"exit 1filocal backup_time=$(date +'%Y%m%d_%H%M%S')local inc_backup_path="${INC_BACKUP_DIR}/inc_${backup_time}"log "开始执行增量备份,备份路径:${inc_backup_path},基准路径:${latest_full}"# 执行增量备份(基于最新全量备份)xtrabackup --user="${DB_USER}" --password="${DB_PASS}" --backup --target-dir="${inc_backup_path}" --incremental-basedir="${latest_full}" &>> "${LOG_FILE}"if [ $? -eq 0 ]; thenlog "增量备份完成,开始准备备份文件"# 准备增量备份(用于恢复)xtrabackup --prepare --target-dir="${inc_backup_path}" &>> "${LOG_FILE}"if [ $? -eq 0 ]; thenlog "增量备份准备完成"# 记录最新增量备份路径(供下一次增量备份使用,若需多轮增量)echo "${inc_backup_path}" > "${BACKUP_BASE_DIR}/latest_inc_backup.txt"elselog "错误:增量备份准备失败"rm -rf "${inc_backup_path}"exit 1fielselog "错误:增量备份执行失败"rm -rf "${inc_backup_path}"exit 1fi
}# 主逻辑:根据传入参数执行对应操作
case "$1" infull)full_backupclean_old_backups;;inc)incremental_backupclean_old_backups;;*)echo "用法:$0 [full|inc]"echo " full: 执行全量备份"echo " inc: 执行增量备份(需先执行过全量备份)"exit 1;;
esaclog "本次备份任务执行完毕"
exit 0
注意:
- 修改配置参数:打开脚本,替换
DB_PASS(数据库密码)、BACKUP_BASE_DIR(备份根目录)等参数为实际值。 - 添加执行权限:执行命令
chmod +x mysql_backup.sh,赋予脚本可执行权限。 - 执行备份:
- 全量备份:
./mysql_backup.sh full - 增量备份:
./mysql_backup.sh inc(需先执行过全量备份)
- 全量备份:
- 定时任务配置(示例):
- 执行
crontab -e,添加如下内容(每周日凌晨 1 点全量备份,其余时间凌晨 1 点增量备份):
- 执行
0 1 * * 0 /path/to/mysql_backup.sh full # 每周日全量备份
0 1 * * 1-6 /path/to/mysql_backup.sh inc # 周一到周六增量备份七、xtrabackup 备份恢复脚本
脚本说明
- 该脚本用于恢复通过前述全量 + 增量备份生成的备份文件,支持自动合并增量备份到全量备份、清理数据目录、权限调整等步骤。
- 需根据实际环境修改 “配置参数”,尤其要准确填写全量备份路径、增量备份路径(多个增量需按顺序填写)及 MySQL 数据目录。
- 恢复过程会停止 MySQL 服务并清空数据目录,操作前请确认备份文件完整且已做好数据备份,避免数据丢失。
#!/bin/bash
# 配置参数(根据实际环境修改)
DB_USER="root" # 数据库用户名
DB_PASS="your_db_password" # 数据库密码
BACKUP_BASE_DIR="/data/mysql_backup" # 备份根目录
FULL_BACKUP_PATH="${BACKUP_BASE_DIR}/full/full_20240520_010000" # 全量备份具体路径
# 增量备份路径列表(按备份时间顺序填写,第一个为基于全量的增量,后续为基于前一个增量的增量)
INC_BACKUP_PATHS=("${BACKUP_BASE_DIR}/incremental/inc_20240521_010000""${BACKUP_BASE_DIR}/incremental/inc_20240522_010000"
)
MYSQL_DATA_DIR="/var/lib/mysql" # MySQL数据目录(默认路径,需确认)
LOG_FILE="${BACKUP_BASE_DIR}/restore.log" # 恢复日志文件# 日志输出函数
log() {echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" >> "${LOG_FILE}"
}# 检查xtrabackup是否安装
if ! command -v xtrabackup &> /dev/null; thenlog "错误:未安装xtrabackup工具,请先安装后再执行脚本"exit 1
fi# 检查全量备份目录是否存在
if [ ! -d "${FULL_BACKUP_PATH}" ]; thenlog "错误:全量备份目录${FULL_BACKUP_PATH}不存在"exit 1
fi# 检查增量备份目录是否存在(若配置了增量)
if [ ${#INC_BACKUP_PATHS[@]} -gt 0 ]; thenfor inc_path in "${INC_BACKUP_PATHS[@]}"; doif [ ! -d "${inc_path}" ]; thenlog "错误:增量备份目录${inc_path}不存在"exit 1fidone
fi# 停止MySQL服务
log "开始停止MySQL服务"
systemctl stop mysqld
if [ $? -ne 0 ]; thenlog "错误:停止MySQL服务失败"exit 1
fi
log "MySQL服务已停止"# 清空MySQL数据目录
log "开始清空MySQL数据目录:${MYSQL_DATA_DIR}"
rm -rf "${MYSQL_DATA_DIR}"/*
if [ $? -ne 0 ]; thenlog "错误:清空数据目录失败"# 尝试启动MySQL服务后退出systemctl start mysqldexit 1
fi
log "数据目录清空完成"# 准备全量备份
log "开始准备全量备份:${FULL_BACKUP_PATH}"
xtrabackup --prepare --apply-log-only --user="${DB_USER}" --password="${DB_PASS}" --target-dir="${FULL_BACKUP_PATH}" &>> "${LOG_FILE}"
if [ $? -ne 0 ]; thenlog "错误:准备全量备份失败"systemctl start mysqldexit 1
fi
log "全量备份准备完成"# 合并增量备份(若有)
if [ ${#INC_BACKUP_PATHS[@]} -gt 0 ]; thenlocal inc_count=${#INC_BACKUP_PATHS[@]}local index=1for inc_path in "${INC_BACKUP_PATHS[@]}"; dolog "开始合并第${index}个增量备份:${inc_path}"# 最后一个增量备份合并时移除--apply-log-only参数if [ ${index} -eq ${inc_count} ]; thenxtrabackup --prepare --user="${DB_USER}" --password="${DB_PASS}" --target-dir="${FULL_BACKUP_PATH}" --incremental-dir="${inc_path}" &>> "${LOG_FILE}"elsextrabackup --prepare --apply-log-only --user="${DB_USER}" --password="${DB_PASS}" --target-dir="${FULL_BACKUP_PATH}" --incremental-dir="${inc_path}" &>> "${LOG_FILE}"fiif [ $? -ne 0 ]; thenlog "错误:合并增量备份${inc_path}失败"systemctl start mysqldexit 1filog "第${index}个增量备份合并完成"index=$((index + 1))done
fi# 执行恢复操作
log "开始执行恢复,目标数据目录:${MYSQL_DATA_DIR}"
xtrabackup --copy-back --user="${DB_USER}" --password="${DB_PASS}" --target-dir="${FULL_BACKUP_PATH}" &>> "${LOG_FILE}"
if [ $? -ne 0 ]; thenlog "错误:恢复数据失败"systemctl start mysqldexit 1
fi
log "数据恢复完成"# 调整数据目录权限
log "开始调整数据目录权限"
chown -R mysql:mysql "${MYSQL_DATA_DIR}"
if [ $? -ne 0 ]; thenlog "错误:调整权限失败"systemctl start mysqldexit 1
fi
log "权限调整完成"# 启动MySQL服务
log "开始启动MySQL服务"
systemctl start mysqld
if [ $? -ne 0 ]; thenlog "错误:启动MySQL服务失败"exit 1
fi
log "MySQL服务已启动"log "所有恢复步骤执行完毕,请登录数据库验证数据完整性"
exit 0
注意:
- 修改配置参数:重点替换
DB_PASS(数据库密码)、FULL_BACKUP_PATH(实际全量备份文件夹路径)、INC_BACKUP_PATHS(增量备份文件夹路径列表,按备份时间先后排序)、MYSQL_DATA_DIR(MySQL 实际数据目录)。 - 添加执行权限:执行
chmod +x mysql_restore.sh赋予脚本可执行权限。 - 执行恢复:运行
./mysql_restore.sh,等待脚本执行完成后,登录数据库验证数据是否完整。

