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
mysqlpump (MySQL 8推荐)# mysqlpump 支持并行备份,速度更快
docker exec mysql8 mysqlpump -uroot -p密码 --all-databases > backup.sql
# 恢复所有数据库
cat backup.sql | docker exec -i mysql8 mysql -uroot -p密码
# 恢复指定数据库
docker exec -i mysql8 mysql -uroot -p密码 mydatabase < mydatabase_backup.sql
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"
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 "恢复完成"
# 停止MySQL容器
docker stop mysql8
# 备份整个数据目录
docker cp mysql8:/var/lib/mysql ./mysql_backup_$(date +%Y%m%d)
# 启动容器
docker start mysql8
# 停止容器
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
docker-compose.ymlversion: '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:
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
# 编辑crontab
crontab -e
# 每天凌晨2点备份
0 2 * * * /opt/scripts/mysql_backup.sh
# 每周日凌晨3点完整备份
0 3 * * 0 /opt/scripts/mysql_full_backup.sh
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
# 安装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
加密备份:
# 加密备份文件
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
# 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
这个方案提供了从简单到复杂的多种备份恢复方式,可以根据实际需求选择合适的方案。建议定期测试恢复流程,确保备份的有效性。