欢迎光临武汉华金科技
马上发布信息
详情描述
Docker下Mysql8数据备份与恢复实现

1. 基础备份方法

1.1 使用 mysqldump 备份

# 基本备份命令
docker exec [容器名] mysqldump -u[用户名] -p[密码] [数据库名] > backup.sql

# 示例:备份所有数据库
docker exec mysql8 mysqldump -uroot -p密码 --all-databases > all_backup.sql

# 示例:备份指定数据库
docker exec mysql8 mysqldump -uroot -p密码 mydatabase > mydatabase_backup.sql

# 带时间戳的备份
docker exec mysql8 mysqldump -uroot -p密码 --all-databases > backup_$(date +%Y%m%d_%H%M%S).sql

1.2 使用 mysqlpump (MySQL 8推荐)

# mysqlpump 支持并行备份,速度更快
docker exec mysql8 mysqlpump -uroot -p密码 --all-databases > backup.sql

2. 恢复数据

2.1 从SQL文件恢复

# 恢复所有数据库
cat backup.sql | docker exec -i mysql8 mysql -uroot -p密码

# 恢复指定数据库
docker exec -i mysql8 mysql -uroot -p密码 mydatabase < mydatabase_backup.sql

3. 完整备份脚本

3.1 创建备份脚本 backup.sh

#!/bin/bash

# 配置变量
MYSQL_CONTAINER="mysql8"
MYSQL_USER="root"
MYSQL_PASSWORD="your_password"
BACKUP_DIR="/opt/mysql_backups"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=7

# 创建备份目录
mkdir -p $BACKUP_DIR

# 备份所有数据库
echo "开始备份 MySQL 数据库..."
docker exec $MYSQL_CONTAINER mysqldump \
  -u$MYSQL_USER \
  -p$MYSQL_PASSWORD \
  --all-databases \
  --routines \
  --events \
  --triggers \
  --single-transaction \
  --quick \
  > $BACKUP_DIR/backup_$DATE.sql

# 压缩备份文件
gzip $BACKUP_DIR/backup_$DATE.sql

# 删除旧备份
find $BACKUP_DIR -name "*.sql.gz" -mtime +$RETENTION_DAYS -delete

echo "备份完成: $BACKUP_DIR/backup_$DATE.sql.gz"

3.2 创建恢复脚本 restore.sh

#!/bin/bash

# 配置变量
MYSQL_CONTAINER="mysql8"
MYSQL_USER="root"
MYSQL_PASSWORD="your_password"
BACKUP_FILE=$1

if [ -z "$BACKUP_FILE" ]; then
  echo "请指定备份文件"
  echo "用法: $0 <备份文件>"
  exit 1
fi

# 检查文件是否存在
if [ ! -f "$BACKUP_FILE" ]; then
  echo "备份文件不存在: $BACKUP_FILE"
  exit 1
fi

echo "开始恢复数据库..."

# 如果是压缩文件
if [[ $BACKUP_FILE == *.gz ]]; then
  gunzip -c $BACKUP_FILE | docker exec -i $MYSQL_CONTAINER mysql -u$MYSQL_USER -p$MYSQL_PASSWORD
else
  cat $BACKUP_FILE | docker exec -i $MYSQL_CONTAINER mysql -u$MYSQL_USER -p$MYSQL_PASSWORD
fi

echo "恢复完成"

4. 使用物理备份 (直接复制数据文件)

4.1 备份数据文件

# 停止MySQL容器
docker stop mysql8

# 备份整个数据目录
docker cp mysql8:/var/lib/mysql ./mysql_backup_$(date +%Y%m%d)

# 启动容器
docker start mysql8

4.2 恢复数据文件

# 停止容器
docker stop mysql8

# 清空原数据目录
docker exec mysql8 rm -rf /var/lib/mysql/*

# 恢复备份数据
docker cp ./mysql_backup/ mysql8:/var/lib/mysql/

# 修改权限
docker exec mysql8 chown -R mysql:mysql /var/lib/mysql

# 启动容器
docker start mysql8

5. Docker Compose 集成方案

5.1 docker-compose.yml

version: '3.8'

services:
  mysql:
    image: mysql:8.0
    container_name: mysql8
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-rootpassword}
      MYSQL_DATABASE: ${MYSQL_DATABASE:-mydb}
      MYSQL_USER: ${MYSQL_USER:-myuser}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD:-mypassword}
    ports:
      - "3306:3306"
    volumes:
      - mysql_data:/var/lib/mysql
      - ./backup:/backup
      - ./scripts:/scripts
    command: 
      --default-authentication-plugin=mysql_native_password
      --character-set-server=utf8mb4
      --collation-server=utf8mb4_unicode_ci

volumes:
  mysql_data:

5.2 备份服务扩展

version: '3.8'

services:
  mysql:
    # ... 同上 ...

  backup:
    image: mysql:8.0
    container_name: mysql_backup
    restart: "no"
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-rootpassword}
    volumes:
      - ./backup:/backup
      - ./scripts:/scripts
    entrypoint: ["/bin/bash", "/scripts/backup.sh"]
    depends_on:
      - mysql

6. 自动化备份方案

6.1 使用Cron定时备份

# 编辑crontab
crontab -e

# 每天凌晨2点备份
0 2 * * * /opt/scripts/mysql_backup.sh

# 每周日凌晨3点完整备份
0 3 * * 0 /opt/scripts/mysql_full_backup.sh

6.2 高级备份脚本 mysql_backup.sh

#!/bin/bash

# 配置
CONTAINER_NAME="mysql8"
MYSQL_USER="root"
MYSQL_PASSWORD=$(cat /run/secrets/mysql_root_password)
BACKUP_BASE="/backup/mysql"
LOG_FILE="/var/log/mysql_backup.log"
DATE=$(date +%Y%m%d)
WEEK=$(date +%V)

# 创建目录
DAILY_DIR="$BACKUP_BASE/daily/$DATE"
WEEKLY_DIR="$BACKUP_BASE/weekly/week_$WEEK"
mkdir -p $DAILY_DIR
mkdir -p $WEEKLY_DIR

# 备份函数
backup_database() {
    local db_name=$1
    local output_file="$DAILY_DIR/${db_name}.sql.gz"

    echo "$(date): 开始备份数据库 $db_name" >> $LOG_FILE

    docker exec $CONTAINER_NAME mysqldump \
        -u$MYSQL_USER \
        -p$MYSQL_PASSWORD \
        --single-transaction \
        --routines \
        --events \
        $db_name | gzip > $output_file

    if [ $? -eq 0 ]; then
        echo "$(date): 备份成功: $output_file" >> $LOG_FILE
        # 如果是周日,保留周备份
        if [ $(date +%u) -eq 7 ]; then
            cp $output_file "$WEEKLY_DIR/${db_name}.sql.gz"
        fi
    else
        echo "$(date): 备份失败: $db_name" >> $LOG_FILE
    fi
}

# 获取所有数据库(排除系统库)
DATABASES=$(docker exec $CONTAINER_NAME mysql -u$MYSQL_USER -p$MYSQL_PASSWORD \
    --skip-column-names \
    -e "SELECT schema_name FROM information_schema.schemata WHERE schema_name NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys')")

# 备份每个数据库
for DB in $DATABASES; do
    backup_database $DB
done

# 清理旧备份(保留7天,4周)
find $BACKUP_BASE/daily -type f -mtime +7 -delete
find $BACKUP_BASE/weekly -type f -mtime +28 -delete

echo "$(date): 备份任务完成" >> $LOG_FILE

7. 使用Percona XtraBackup (物理热备份)

# 安装XtraBackup
docker run -it --rm \
  -v mysql_data:/var/lib/mysql \
  -v $(pwd)/backup:/backup \
  percona/percona-xtrabackup:8.0 \
  xtrabackup --backup \
  --host=host.docker.internal \
  --user=root \
  --password=password \
  --target-dir=/backup/full

8. 最佳实践建议

加密备份

# 加密备份文件
mysqldump -u root -p dbname | gzip | openssl enc -aes-256-cbc -salt -out backup.sql.gz.enc

验证备份完整性

# 检查备份文件
gzip -t backup.sql.gz
# 或者
mysqlcheck -u root -p < backup.sql

多地点存储

  • 本地服务器
  • 云存储(S3、OSS等)
  • 离线存储

监控备份状态

# 检查备份文件大小
if [ $(stat -c%s "backup.sql.gz") -lt 1000 ]; then
 echo "备份文件异常小" | mail -s "MySQL备份告警" admin@example.com
fi

9. 紧急恢复流程

快速恢复步骤

# 1. 停止应用服务
docker-compose stop app
2. 恢复数据库

./restore.sh latest_backup.sql.gz

3. 验证数据

docker exec mysql8 mysql -uroot -p -e "SHOW DATABASES;"

4. 启动应用

docker-compose start app



这个方案提供了从简单到复杂的多种备份恢复方式,可以根据实际需求选择合适的方案。建议定期测试恢复流程,确保备份的有效性。