Docker环境下的MySQL全库分离备份及还原教程

 更新时间:2026年06月28日 14:14:50   作者:凡间晨光  
在Docker容器化部署成为主流的今天,MySQL数据库的备份与还原面临着环境隔离与数据安全的双重挑战,本文基于实战经验,详细介绍Docker环境下MySQL全库分离备份方案,需要的朋友可以参考下

引言

在Docker容器化部署成为主流的今天,MySQL数据库的备份与还原面临着“环境隔离”与“数据安全”的双重挑战。传统全库备份不仅占用大量资源,还难以应对单库异常的快速恢复需求。

本文基于实战经验,详细介绍Docker环境下MySQL全库分离备份方案——通过按业务库拆分备份、自动化脚本执行、压缩存储等技术,实现“轻量备份-精准还原-安全存储”的全流程管理。

一、Docker中mysql分离备份

1. 数据准备(待备份机器上MySQL的容器id、用户、密码)

执行docker ps | grep pxc或者docker ps | grep mysql查看mysql容器,一般是3306端口的那个容器,记录容器id(一般为第一列)

2. 数据库备份步骤

1.创建并执行备份脚本(bak.sh)

#修改以下脚本中的配置项内容,直接执行以下命令即可完成数据库备份

cat > /bak/bak.sh << 'EOF'
#!/bin/bash
# ========== 配置(请根据实际情况修改) ==========
CONTAINER_NAME="xxxxx"   #您的MySQL容器名称或id
BACKUP_DIR="/bak/mysql"  #修改为要备份的位置目录
MYSQL_USER="xxxxx"       #修改为真实数据库用户名
MYSQL_PASSWORD="xxxxx"   #修改为真实数据库密码
DATE=$(date +%Y%m%d_%H%M%S)
# ========== 创建备份目录==========
mkdir -p ${BACKUP_DIR}
# ========== 获取数据库列表(过滤系统库) ==========
DATABASES=$(docker exec ${CONTAINER_NAME} mysql -u${MYSQL_USER} -p${MYSQL_PASSWORD} -e "SHOW DATABASES;" 2>/dev/null | \
            grep -Ev "^(Database|information_schema|performance_schema|mysql|sys)$")
# ========== 逐个备份 ==========
for DB in ${DATABASES}; do
    echo "正在备份数据库: ${DB}"
    BACKUP_FILE="${BACKUP_DIR}/${DB}_${DATE}.sql"
    docker exec ${CONTAINER_NAME} mysqldump -u${MYSQL_USER} -p${MYSQL_PASSWORD} \
        --single-transaction \
        --routines \
        --triggers \
        --events \
        -B ${DB} > ${BACKUP_FILE} 2>/dev/null
    if [ $? -eq 0 ]; then
        echo "✓ 备份成功: ${BACKUP_FILE}"
    else
        echo "✗ 备份失败: ${DB}"
        rm -f ${BACKUP_FILE}
    fi
done
echo "所有数据库备份完成!备份目录:${BACKUP_DIR}"
EOF
chmod +x /bak/bak.sh
echo "已更新并添加执行权限,开始备份数据库"
/bak/bak.sh

2.压缩备份结果

tar -czf /bak/mysql_backup_$(date +%Y%m%d_%H%M%S).tar.gz -C /bak mysql

注意:如果在Windows上创建的脚本,在粘贴到Linux后,需要将Windows 风格的换行符(CRLF,即\r\n)换成 Linux 系统期望的是 Unix 风格的换行符(LF,即\n),执行以下命令即可:sed -i 's/\r$//' /bak/bak.sh

二、Docker中mysql一键还原

1.数据准备(查看待还原机器上MySQL的容器id、用户、密码)

执行docker ps | grep pxc或者docker ps | grep mysql查看mysql容器,一般是3306端口的那个容器,记录容器id(一般为第一列)

2.数据库还原步骤

1. 创建目录bak,将备份文件复制并解压到bak目录

#创建目录bak
mkdir -p /bak/mysql
#解压缩命令
tar -zxvf /bak/mysql_backup_20260608_112915.tar.gz -C /bak

2. 创建并执行还原脚本(restore.sh)

#修改以下脚本中的配置项内容,直接执行以下命令即可完成数据库恢复

cat > /bak/restore.sh << 'EOF'
#!/bin/bash

# ===== 配置区(与备份脚本保持一致) =====================
CONTAINER_NAME="xxxxx"   #您的MySQL容器名称或id
BACKUP_DIR="/bak/mysql"  #修改为备份文件的位置目录
MYSQL_USER="xxxxx"       #修改为真实数据库用户名
MYSQL_PASSWORD="xxxxx"   #修改为真实数据库密码
# =============================================

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

# 定义需要跳过的系统数据库列表(恢复时忽略)
SKIP_DATABASES=(
    "mysql"
    "information_schema"
    "performance_schema"
    "sys"
    "test"
)

# 校验备份目录
if [ ! -d "${BACKUP_DIR}" ]; then
    echo -e "${RED}错误:备份目录 ${BACKUP_DIR} 不存在!${NC}"
    exit 1
fi

# 检查容器是否运行
if ! docker ps --filter "id=${CONTAINER_NAME}" --format "{{.ID}}" | grep -q "${CONTAINER_NAME}"; then
    echo -e "${RED}错误:容器 ${CONTAINER_NAME} 未运行或不存在!${NC}"
    exit 1
fi

# 测试 MySQL 连接
echo -e "${YELLOW}测试 MySQL 连接...${NC}"
if ! docker exec -i "${CONTAINER_NAME}" mysql -u"${MYSQL_USER}" -p"${MYSQL_PASSWORD}" -e "SELECT 1;" >/dev/null 2>&1; then
    echo -e "${RED}错误:无法连接 MySQL,请检查用户名或密码!${NC}"
    exit 1
fi
echo -e "${GREEN}✓ 连接成功${NC}"

# 统计变量
TOTAL=0
SUCCESS=0
SKIPPED=0
FAILED=0

# 遍历所有 sql 文件
for SQL_FILE in "${BACKUP_DIR}"/*.sql; do
    [ -e "$SQL_FILE" ] || continue

    # 提取数据库名:删除末尾时间戳(_YYYYMMDD_HHMMSS.sql),保留完整名称(含 - 等特殊字符)
    DB_NAME=$(basename "${SQL_FILE}" | sed 's/_[0-9]\{8\}_[0-9]\{6\}\.sql$//')

    # 检查是否在跳过列表中
    SKIP=0
    for SKIP_DB in "${SKIP_DATABASES[@]}"; do
        if [ "${DB_NAME}" == "${SKIP_DB}" ]; then
            SKIP=1
            break
        fi
    done

    if [ ${SKIP} -eq 1 ]; then
        echo "=========================================="
        echo -e "${YELLOW}⏭️ 跳过系统数据库:${DB_NAME}${NC}"
        ((SKIPPED++))
        continue
    fi

    echo "============================================="
    echo -e "${YELLOW}开始恢复数据库:${DB_NAME}${NC}"
    echo "文件:${SQL_FILE}"
    ((TOTAL++))

    # 执行恢复,捕获输出
    TEMP_LOG=$(mktemp)
    docker exec -i "${CONTAINER_NAME}" mysql -u"${MYSQL_USER}" -p"${MYSQL_PASSWORD}" --force < "${SQL_FILE}" > "${TEMP_LOG}" 2>&1
    EXIT_CODE=$?

    # 判断是否真正失败:排除 ERROR 1105(PXC 严格模式警告)
    OTHER_ERRORS=$(grep -i "ERROR" "${TEMP_LOG}" | grep -v "ERROR 1105")

    if [ ${EXIT_CODE} -eq 0 ] && [ -z "${OTHER_ERRORS}" ]; then
        # 检查是否只有 1105 警告
        # if grep -qi "ERROR 1105" "${TEMP_LOG}"; then
            # echo -e "${YELLOW}⚠️ 检测到 PXC 严格模式警告(已忽略),数据已正常恢复${NC}"
        # fi
        echo -e "${GREEN}✅ ${DB_NAME} 恢复成功${NC}"
        ((SUCCESS++))
    else
        echo -e "${RED}❌ ${DB_NAME} 恢复失败,错误信息:${NC}"
        if [ -n "${OTHER_ERRORS}" ]; then
            echo "${OTHER_ERRORS}" | head -10
        else
            tail -5 "${TEMP_LOG}"
        fi
        ((FAILED++))
    fi

    rm -f "${TEMP_LOG}"
done

# 输出汇总
echo "============================================="
echo -e "${GREEN}批量恢复执行完毕!${NC}"
echo "总计处理:$((TOTAL + SKIPPED)) 个文件"
echo "  ✅ 成功恢复:${SUCCESS}"
echo "  ⏭️  跳过系统库:${SKIPPED}"
if [ ${FAILED} -gt 0 ]; then
    echo -e "  ${RED}❌ 恢复失败:${FAILED}${NC}"
else
    echo "  ❌ 恢复失败:0"
fi
EOF

chmod +x /bak/restore.sh
echo "已更新并添加执行权限,开始恢复数据库"
/bak/restore.sh

三、总结

这套Docker环境下的MySQL全库分离备份还原方案,适合中小规模业务,脚本可直接复用。核心是按库分离备份(方便单独还原某个库)和自动化脚本(减少人工操作)。可以结合crontab设置定时备份,比如每天凌晨3点执行:

crontab -e  # 添加一行
0 3 * * * /bak/bak.sh && tar -czf /bak/mysql_backup_$(date +%Y%m%d).tar.gz -C /bak mysql --remove-files

数据安全无小事,定期备份+定期还原测试,才能确保关键时刻不掉链子。有问题欢迎在评论区交流,觉得有用的话别忘了点赞收藏!

以上就是Docker环境下的MySQL全库分离备份及还原教程的详细内容,更多关于Docker下MySQL分离备份及还原的资料请关注脚本之家其它相关文章!

相关文章

最新评论