企业级 MySQL 8.0 物理备份实践:使用 XtraBackup 实现全量与增量自动备份

企业级 MySQL 8.0 物理备份实践:使用 XtraBackup 实现全量与增量自动备份

1. 为什么选择 XtraBackup?

  • 热备份:备份期间不影响数据库的读写。
  • 物理备份:直接拷贝数据文件,恢复速度极快。
  • 增量备份:仅备份自上次以来发生变化的数据块,节省空间。

2. 安装过程中的"深坑"

在 CentOS 7 上安装,最常见的问题是依赖项找不到或官方源下载过慢。

第一步:安装 Percona 源

bash 复制代码
sudo yum install -y https://repo.percona.com/yum/percona-release-latest.noarch.rpm

第二步:配置 ps80 库

bash 复制代码
sudo percona-release setup ps80

第三步:解决依赖(重点)

qpress 压缩工具不在 Percona 源里,必须先装 EPEL。如果下载慢,建议换成阿里源或清华源:

bash 复制代码
sudo yum install -y epel-release
sudo yum install -y percona-xtrabackup-80 qpress

3. 核心备份脚本:db_backup.sh

这个脚本集成了三个高级功能:

  1. 智能连接:Socket 找不到时自动切 TCP/IP。
  2. 重名处理 :同日多次运行自动加 _1, _2 后缀。
  3. 链式增量:永远基于"上一次成功备份"进行增量。
bash 复制代码
#!/bin/bash
# ========================================================
# MySQL 全自动物理备份脚本 (XtraBackup 8.0)
# ========================================================

# --- 基础配置 ---
USER="bkpuser"
PASSWORD="bkpuser@2026"
SOCKET="/tmp/mysql.sock" # 宝塔等面板常在 /tmp/ 下
HOST="127.0.0.1"        # 备用连接地址
DATADIR="/www/server/data" # 数据库实际存储路径
BACKUP_BASE="/data/backup" # 备份存放总目录

# --- 自动处理时间与目录 ---
DATE=$(date +%F)
DAY_OF_WEEK=$(date +%u) # 1-7 (7为周日)
LOG_FILE="$BACKUP_BASE/backup.log"

mkdir -p "$BACKUP_BASE/full" "$BACKUP_BASE/inc"
exec >> "$LOG_FILE" 2>&1

echo "==================== 备份开始: $(date '+%Y-%m-%d %H:%M:%S') ===================="

# 1. 智能连接策略
if [ -S "$SOCKET" ]; then
    CONN_OPTS="--socket=$SOCKET"
else
    echo "[Warning] Socket文件不存在,尝试通过HOST连接..."
    CONN_OPTS="--host=$HOST --port=3306"
fi

# 2. 目录冲突函数:如果目录存在,则重命名为 _1, _2...
get_safe_dir() {
    local b_dir=$1; local b_name=$2; local target="$b_dir/$b_name"
    local count=1
    while [ -d "$target" ]; do
        target="${b_dir}/${b_name}_${count}"
        ((count++))
    done
    echo "$target"
}

# 3. 确定备份基准
LAST_SUCCESS=$(ls -td $BACKUP_BASE/full/* $BACKUP_BASE/inc/* 2>/dev/null | head -1)

# 4. 执行备份逻辑
if [ "$DAY_OF_WEEK" -eq 7 ] || [ -z "$LAST_SUCCESS" ]; then
    # 【全量备份】条件:周日 或 没有任何备份记录
    T_DIR=$(get_safe_dir "$BACKUP_BASE/full" "${DATE}_full")
    echo "[Info] 执行全量备份 -> $T_DIR"
    xtrabackup --backup $CONN_OPTS --user=$USER --password=$PASSWORD --datadir=$DATADIR --target-dir=$T_DIR --no-server-version-check
else
    # 【增量备份】条件:周一至周六 且 存在基准
    T_DIR=$(get_safe_dir "$BACKUP_BASE/inc" "${DATE}_inc")
    echo "[Info] 执行增量备份 -> $T_DIR (基准: $LAST_SUCCESS)"
    xtrabackup --backup $CONN_OPTS --user=$USER --password=$PASSWORD --datadir=$DATADIR --target-dir=$T_DIR --incremental-basedir=$LAST_SUCCESS --no-server-version-check
fi

# 5. 结果校验
if [ $? -eq 0 ]; then
    echo "[Success] 备份已完成。"
else
    echo "[Error] 备份进程异常退出!"
    [ -d "$T_DIR" ] && rm -rf "$T_DIR" # 清理残余空目录
    exit 1
fi

# 6. 自动清理 (保留近30天的备份)
# find $BACKUP_BASE -mtime +30 -type d -exec rm -rf {} \;
echo "==================== 备份结束: $(date '+%Y-%m-%d %H:%M:%S') ===================="

4. 如何在灾难发生时进行恢复?

增量备份的恢复像"接龙"一样,必须按顺序准备。

步骤 A:整理全量(Prepare)

这一步是把未提交的事务回滚,应用日志。

bash 复制代码
xtrabackup --prepare --apply-log-only --target-dir=/data/backup/full/2026-01-04_full

步骤 B:合并所有增量

按照时间顺序,依次将增量包合并进全量包。最后一个包不需要加 --apply-log-only

bash 复制代码
# 合并周一增量
xtrabackup --prepare --apply-log-only --target-dir=/data/backup/full/2026-01-04_full --incremental-dir=/data/backup/inc/2026-01-05_inc
# ... 如果还有周二、周三,以此类推 ...

步骤 C:恢复到数据目录

停止 MySQL 并清理旧数据(注意先做原始数据的移动备份!):

bash 复制代码
systemctl stop mysqld
mv /www/server/data /www/server/data_old
mkdir /www/server/data
xtrabackup --copy-back --target-dir=/data/backup/full/2026-01-04_full
chown -R mysql:mysql /www/server/data
systemctl start mysqld

5. 日常维护建议

  1. 权限 :确保执行脚本的用户对 /data/backup 有写权限。
  2. 空间 :物理备份占用空间大,建议开启 find 命令清理 30 天前的备份。
  3. 验证:备份成功不代表能恢复,建议每季度拉取一个增量包到测试机做恢复演练。

相关推荐
0xDevNull4 小时前
MySQL数据冷热分离详解
后端·mysql
科技小花4 小时前
数据治理平台架构演进观察:AI原生设计如何重构企业数据管理范式
数据库·重构·架构·数据治理·ai-native·ai原生
一江寒逸4 小时前
零基础从入门到精通MySQL(中篇):进阶篇——吃透多表查询、事务核心与高级特性,搞定复杂业务SQL
数据库·sql·mysql
D4c-lovetrain4 小时前
linux个人心得22 (mysql)
数据库·mysql
阿里小阿希5 小时前
CentOS7 PostgreSQL 9.2 升级到 15 完整教程
数据库·postgresql
荒川之神5 小时前
Oracle 数据仓库雪花模型设计(完整实战方案)
数据库·数据仓库·oracle
做个文艺程序员5 小时前
MySQL安全加固十大硬核操作
数据库·mysql·安全
不吃香菜学java5 小时前
Redis简单应用
数据库·spring boot·tomcat·maven
一个天蝎座 白勺 程序猿5 小时前
Apache IoTDB(15):IoTDB查询写回(INTO子句)深度解析——从语法到实战的ETL全链路指南
数据库·apache·etl·iotdb
不知名的老吴5 小时前
Redis的延迟瓶颈:TCP栈开销无法避免
数据库·redis·缓存