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
多地点存储:
监控备份状态:
# 检查备份文件大小
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
这个方案提供了从简单到复杂的多种备份恢复方式,可以根据实际需求选择合适的方案。建议定期测试恢复流程,确保备份的有效性。