跳至正文
零海博客

零海博客

零海博客

零海博客

  • 网络安全
  • java
  • 建站
  • 运维
  • 未分类
  • 网络安全
  • java
  • 建站
  • 运维
  • 未分类
关

搜索

数据库运维

Docker MySQL 备份与恢复指南

作者 wangjian@2
2026年8月6日 6 分钟阅读
0

Docker MySQL 备份与恢复指南,讲解容器内MySQL数据库定时备份、导出导入、快照备份、数据恢复实操步骤,包含docker命令脚本与常见问题排查。

如果要查看怎么用docker安装mysql请查看https://blog.zerosea.cn/install-mysql-with-docker

备份整个数据库

温馨提示

出现以下错误时,

mysqldump: [Warning] Using a password on the command line interface can be insecure.

因为新版本的mysql(MySQL 5.6、5.7、8.0 及以后)不推荐在命令行中直接使用密码 执行的时候加个-i参数从提示符读取密码,下面所有命令都可以这么操作

docker exec -i mysql容器名 mysqldump -u用户名 -p 数据库名 > 数据库备份.sql

方法一:使用 mysqldump 备份整个数据库

# 备份整个数据库(包含所有表的结构和数据)
docker exec mysql容器名 mysqldump -u用户名 -p密码 数据库名 > 数据库备份.sql

# 示例
docker exec mysql_container mysqldump -uroot -p123456 mydatabase > mydatabase_backup.sql

# 仅备份数据库结构(不包含数据)
docker exec mysql容器名 mysqldump -u用户名 -p密码 -d 数据库名 > 数据库结构备份.sql

# 仅备份数据库数据(不包含结构)
docker exec mysql容器名 mysqldump -u用户名 -p密码 -t 数据库名 > 数据库数据备份.sql

方法二:备份所有数据库

# 备份MySQL服务器上的所有数据库
docker exec mysql容器名 mysqldump -u用户名 -p密码 --all-databases > 所有数据库备份.sql

# 排除某些数据库(如系统数据库)
docker exec mysql容器名 mysqldump -u用户名 -p密码 --databases db1 db2 db3 > 指定数据库备份.sql

方法三:压缩备份整个数据库

# 备份并压缩数据库
docker exec mysql容器名 mysqldump -u用户名 -p密码 数据库名 | gzip > 数据库备份.sql.gz

# 备份多个数据库并压缩
docker exec mysql容器名 mysqldump -u用户名 -p密码 --databases db1 db2 | gzip > 多数据库备份.sql.gz

恢复整个数据库

方法一:恢复单个数据库

# 创建数据库(如果不存在)
docker exec mysql容器名 mysql -u用户名 -p密码 -e "CREATE DATABASE IF NOT EXISTS 数据库名"

# 恢复数据库
docker exec -i mysql容器名 mysql -u用户名 -p密码 数据库名 < 数据库备份.sql

# 示例
docker exec -i mysql_container mysql -uroot -p123456 mydatabase < ./mydatabase_backup.sql

方法二:恢复所有数据库

# 从包含所有数据库的备份恢复
docker exec -i mysql容器名 mysql -u用户名 -p密码 < 所有数据库备份.sql

# 示例
docker exec -i mysql_container mysql -uroot -p123456 < ./all_databases_backup.sql

方法三:恢复压缩的数据库备份

# 恢复压缩的数据库备份
gunzip < 数据库备份.sql.gz | docker exec -i mysql容器名 mysql -u用户名 -p密码 数据库名

# 恢复压缩的所有数据库备份
gunzip < 所有数据库备份.sql.gz | docker exec -i mysql容器名 mysql -u用户名 -p密码

备份 MySQL 表

方法一:使用 mysqldump 备份表结构和数据

# 备份单个表(包含结构和数据)
docker exec mysql容器名 mysqldump -u用户名 -p密码 数据库名 表名 > 备份文件.sql

# 示例
docker exec mysql_container mysqldump -uroot -p123456 mydatabase users > users_backup.sql

# 仅备份表结构
docker exec mysql容器名 mysqldump -u用户名 -p密码 -d 数据库名 表名 > 结构备份文件.sql

# 仅备份数据(不包含结构)
docker exec mysql容器名 mysqldump -u用户名 -p密码 -t 数据库名 表名 > 数据备份文件.sql

方法三:使用 SQL 查询导出数据

# 使用 SELECT INTO OUTFILE 导出数据(需要在MySQL内执行)
# 首先进入MySQL容器
docker exec -it mysql容器名 mysql -u用户名 -p密码

# 在MySQL中执行
USE 数据库名;
SELECT * FROM 表名 INTO OUTFILE '/tmp/数据导出.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n';

# 退出MySQL后,将文件复制到主机
docker cp mysql容器名:/tmp/数据导出.csv ./数据导出.csv

方法四:使用 MySQL 客户端导出数据

# 进入MySQL容器
docker exec -it mysql容器名 bash

# 在容器内使用mysql客户端导出数据
mysql -u用户名 -p密码 -e "SELECT * FROM 数据库名.表名" > /tmp/数据导出.txt

# 退出容器并复制文件
exit
docker cp mysql容器名:/tmp/数据导出.txt ./数据导出.txt

方法二:使用 docker exec 和重定向

# 备份表到主机目录
docker exec mysql容器名 mysqldump -u用户名 -p密码 数据库名 表名 > /主机路径/备份文件.sql

# 示例:备份到当前目录
docker exec mysql_container mysqldump -uroot -p123456 mydatabase users > ./users_backup.sql

恢复 MySQL 表

方法一:使用 mysql 命令恢复

# 恢复表(从sql文件)
docker exec -i mysql容器名 mysql -u用户名 -p密码 数据库名 < 备份文件.sql

# 示例
docker exec -i mysql_container mysql -uroot -p123456 mydatabase < ./users_backup.sql

方法二:进入容器内部恢复

# 1. 将备份文件复制到容器中
docker cp 备份文件.sql mysql容器名:/tmp/

# 2. 进入容器
docker exec -it mysql容器名 bash

# 3. 在容器内执行恢复命令
mysql -u用户名 -p密码 数据库名 < /tmp/备份文件.sql

# 4. 退出容器
exit

实用技巧

1. 压缩备份文件

# 备份并压缩
docker exec mysql容器名 mysqldump -u用户名 -p密码 数据库名 表名 | gzip > 备份文件.sql.gz

# 恢复压缩文件
gunzip < 备份文件.sql.gz | docker exec -i mysql容器名 mysql -u用户名 -p密码 数据库名

2. 定时备份脚本

#!/bin/bash
# 数据库定时备份脚本

# 配置变量
CONTAINER_NAME="mysql_container"
DB_USER="root"
DB_PASS="123456"
DB_NAME="mydatabase"
BACKUP_DIR="/path/to/backups"
RETENTION_DAYS=7  # 保留最近7天的备份

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

# 生成带时间戳的备份文件名
BACKUP_FILE="$BACKUP_DIR/${DB_NAME}_backup_$(date +%Y%m%d_%H%M%S).sql"

# 执行备份
docker exec $CONTAINER_NAME mysqldump -u$DB_USER -p$DB_PASS $DB_NAME > $BACKUP_FILE

# 压缩备份文件
gzip $BACKUP_FILE

# 删除超过保留天数的备份文件
find $BACKUP_DIR -name "${DB_NAME}_backup_*.sql.gz" -mtime +$RETENTION_DAYS -delete

# 输出备份信息
echo "Database backup created: ${BACKUP_FILE}.gz"

3. 备份所有数据库的定时脚本

#!/bin/bash
# 所有数据库定时备份脚本

# 配置变量
CONTAINER_NAME="mysql_container"
DB_USER="root"
DB_PASS="123456"
BACKUP_DIR="/path/to/backups"
RETENTION_DAYS=7  # 保留最近7天的备份

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

# 生成带时间戳的备份文件名
BACKUP_FILE="$BACKUP_DIR/all_databases_backup_$(date +%Y%m%d_%H%M%S).sql"

# 备份所有数据库
docker exec $CONTAINER_NAME mysqldump -u$DB_USER -p$DB_PASS --all-databases > $BACKUP_FILE

# 压缩备份文件
gzip $BACKUP_FILE

# 删除超过保留天数的备份文件
find $BACKUP_DIR -name "all_databases_backup_*.sql.gz" -mtime +$RETENTION_DAYS -delete

# 输出备份信息
echo "All databases backup created: ${BACKUP_FILE}.gz"

3. 批量备份多个表

#!/bin/bash
# 定义变量
CONTAINER_NAME="mysql_container"
DB_USER="root"
DB_PASS="123456"
DB_NAME="mydatabase"
TABLES=("users" "products" "orders")  # 要备份的表列表
BACKUP_DIR="/path/to/backups"

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

# 备份每个表
for table in "${TABLES[@]}"; do
    backup_file="$BACKUP_DIR/${table}_backup_$(date +%Y%m%d_%H%M%S).sql"
    docker exec $CONTAINER_NAME mysqldump -u$DB_USER -p$DB_PASS $DB_NAME $table > $backup_file
    echo "Backup created: $backup_file"
done

4. 备份查询结果集

# 备份查询结果(特定条件的数据)
docker exec mysql容器名 mysql -u用户名 -p密码 -e "SELECT * FROM 数据库名.表名 WHERE 条件" > 查询结果.csv

# 示例:备份特定日期后的用户数据
docker exec mysql_container mysql -uroot -p123456 -e "SELECT * FROM mydatabase.users WHERE created_at > '2023-01-01'" > recent_users.csv

# 备份关联查询结果
docker exec mysql_container mysql -uroot -p123456 -e "SELECT u.id, u.name, o.order_id FROM users u JOIN orders o ON u.id = o.user_id" > user_orders.csv

5. 将数据导出为 CSV 格式

# 方法一:使用 mysql 客户端和重定向
docker exec mysql容器名 mysql -u用户名 -p密码 数据库名 -e "SELECT * FROM 表名" | sed 's/\t/","/g; s/^/"/; s/$/"/; s/\n//g' > 数据文件.csv

# 方法二:使用 SQL 导出(需要文件权限)
# 首先在MySQL中执行
docker exec -it mysql容器名 mysql -u用户名 -p密码
mysql> USE 数据库名;
mysql> SELECT * FROM 表名 INTO OUTFILE '/tmp/导出文件.csv'
    FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n';

# 然后复制文件到主机
docker cp mysql容器名:/tmp/导出文件.csv ./导出文件.csv

6. 导入 CSV 数据到 MySQL

# 方法一:使用 mysqlimport
# 首先将CSV文件复制到容器
docker cp ./数据文件.csv mysql容器名:/tmp/
# 然后在容器内执行导入
docker exec mysql容器名 mysqlimport -u用户名 -p密码 --local 数据库名 /tmp/数据文件.csv

# 方法二:使用 LOAD DATA INFILE
docker exec -it mysql容器名 mysql -u用户名 -p密码
mysql> USE 数据库名;
mysql> LOAD DATA INFILE '/tmp/数据文件.csv' INTO TABLE 表名
    FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n';

常见问题与解决方案

1. 权限问题

如果遇到权限错误,确保 MySQL 用户有足够的权限:

-- 在MySQL中授予必要权限
GRANT SELECT, LOCK TABLES ON 数据库名.* TO '用户名'@'%';
FLUSH PRIVILEGES;

2. 字符集问题

备份时指定字符集:

docker exec mysql容器名 mysqldump -u用户名 -p密码 --default-character-set=utf8mb4 数据库名 表名 > 备份文件.sql

3. 大表备份

对于大型表,可以添加以下参数:

# 增加超时时间
docker exec mysql容器名 mysqldump -u用户名 -p密码 --single-transaction --quick 数据库名 表名 > 备份文件.sql

验证备份

检查备份文件大小

ls -lh 备份文件.sql

查看备份文件内容

head -n 20 备份文件.sql
tail -n 20 备份文件.sql

测试恢复(建议在测试环境)

  1. 创建测试数据库
  2. 恢复备份到测试数据库
  3. 检查数据是否完整

最佳实践

  1. 定期备份:设置定时任务定期备份重要表
  2. 多地存储:将备份文件存储在不同位置,防止单点故障
  3. 验证备份:定期验证备份文件的完整性
  4. 命名规范:使用清晰的命名规则,包含数据库名、表名和备份时间
  5. 文档记录:记录备份和恢复的详细步骤和注意事项

自动化备份示例(Docker Compose)

示例一:单个数据库自动备份

如果使用 Docker Compose,可以在 docker-compose.yml 中添加备份服务:

version: "3"
services:
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: yourpassword
      MYSQL_DATABASE: mydatabase
    volumes:
      - mysql_data:/var/lib/mysql

  mysql-backup:
    image: mysql:8.0
    depends_on:
      - mysql
    volumes:
      - ./backups:/backups
    command: |
      sh -c "
      while true; do
        docker exec mysql mysqldump -uroot -pyourpassword mydatabase > /backups/mydatabase_backup_$(date +%Y%m%d_%H%M%S).sql
        find /backups -name 'mydatabase_backup_*.sql' -mtime +7 -delete
        sleep 86400
      done"
    restart: unless-stopped

volumes:
  mysql_data:

示例二:所有数据库自动备份

version: "3"
services:
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: yourpassword
    volumes:
      - mysql_data:/var/lib/mysql

  mysql-backup-all:
    image: mysql:8.0
    depends_on:
      - mysql
    volumes:
      - ./backups:/backups
    command: |
      sh -c "
      while true; do
        docker exec mysql mysqldump -uroot -pyourpassword --all-databases | gzip > /backups/all_databases_backup_$(date +%Y%m%d_%H%M%S).sql.gz
        find /backups -name 'all_databases_backup_*.sql.gz' -mtime +7 -delete
        sleep 86400
      done"
    restart: unless-stopped

volumes:
  mysql_data:

示例三:使用cron进行定时备份

version: "3"
services:
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: yourpassword
      MYSQL_DATABASE: mydatabase
    volumes:
      - mysql_data:/var/lib/mysql
      - ./backups:/backups
    command: |
      sh -c "
      # 创建备份脚本
      cat > /backup_script.sh << 'EOF'
      #!/bin/sh
      DATE=\$(date +%Y%m%d_%H%M%S)
      mysqldump -uroot -p$$MYSQL_ROOT_PASSWORD $$MYSQL_DATABASE > /backups/mydatabase_backup_\$DATE.sql
      gzip /backups/mydatabase_backup_\$DATE.sql
      find /backups -name 'mydatabase_backup_*.sql.gz' -mtime +7 -delete
      EOF

      # 使脚本可执行
      chmod +x /backup_script.sh

      # 启动MySQL并设置cron任务
      docker-entrypoint.sh mysqld &
      echo '0 2 * * * /backup_script.sh' > /etc/crontabs/root
      crond -f
      "

volumes:
  mysql_data:

数据备份与迁移专题

导出特定字段数据

# 导出表的特定字段
docker exec mysql容器名 mysql -u用户名 -p密码 -e "SELECT id, name, email FROM 数据库名.表名" > 部分字段.csv

# 导出带有计算的查询结果
docker exec mysql容器名 mysql -u用户名 -p密码 -e "SELECT id, name, COUNT(*) as order_count FROM 数据库名.表名 GROUP BY id" > 统计数据.csv

跨数据库数据迁移

# 从一个MySQL容器导出数据到另一个容器
# 1. 从源容器导出
docker exec source_mysql mysqldump -u用户名 -p密码 -t 源数据库 源表 > data.sql

# 2. 将数据导入目标容器
docker exec -i target_mysql mysql -u用户名 -p密码 目标数据库 < data.sql

# 注意:确保目标表结构与源表兼容,或先创建表结构

大数据量分批导出

# 分批导出大数据量表(每次1000条)
#!/bin/bash
CONTAINER="mysql_container"
DB_USER="root"
DB_PASS="123456"
DB_NAME="mydatabase"
TABLE="large_table"
BATCH_SIZE=1000
OFFSET=0

# 获取总记录数
TOTAL_RECORDS=$(docker exec $CONTAINER mysql -u$DB_USER -p$DB_PASS -e "SELECT COUNT(*) FROM $DB_NAME.$TABLE" | tail -n 1)

# 分批导出
while [ $OFFSET -lt $TOTAL_RECORDS ]; do
    docker exec $CONTAINER mysql -u$DB_USER -p$DB_PASS -e "SELECT * FROM $DB_NAME.$TABLE LIMIT $OFFSET, $BATCH_SIZE" > ${TABLE}_part_${OFFSET}.csv
    OFFSET=$((OFFSET + BATCH_SIZE))
    echo "Exported records up to $OFFSET"
done

数据备份验证

# 验证导出的数据行数
# 1. 统计原表记录数
docker exec mysql容器名 mysql -u用户名 -p密码 -e "SELECT COUNT(*) FROM 数据库名.表名"

# 2. 统计导出文件记录数(不包括标题行)
cat 导出文件.csv | wc -l

# 3. 验证数据一致性(简单示例)
# 比较特定字段的SUM值
ORIGINAL_SUM=$(docker exec mysql容器名 mysql -u用户名 -p密码 -e "SELECT SUM(amount) FROM 数据库名.表名" | tail -n 1)
EXPORTED_SUM=$(cat 导出文件.csv | awk -F',' 'NR>1 {sum+=$3} END {print sum}')
echo "Original sum: $ORIGINAL_SUM, Exported sum: $EXPORTED_SUM"

注意事项

  1. 备份大型表时可能会占用较多系统资源
  2. 在备份过程中表可能会被锁定,影响正常业务
  3. 恢复操作会覆盖现有数据,请谨慎操作
  4. 恢复前建议先备份当前数据,以防意外
  5. 导出CSV文件时注意字符编码问题,可能需要指定–default-character-set参数
  6. 大数据量导出时考虑分批处理,避免内存溢出
  7. 敏感数据导出时注意数据安全,必要时进行加密处理
Docker MySQL 备份与恢复指南
Docker MySQL 备份与恢复指南

标签:

dockermysql
作者

wangjian@2

关注我
其他文章
redis_logo
上一个

Redis 曝出多条零日 RCE 漏洞|Stream 双重释放与 RedisBloom 越界写入风险分析及防范方案

BdThemes
下一个

BdThemes 供应链投毒攻击事件

暂无评论!成为第一个。

发表回复 取消回复

您的邮箱地址不会被公开。 必填项已用 * 标注

近期文章

  • Chrome 高危沙箱逃逸 CVE-2026-84354:一个恶意网页就能在沙箱外执行代码,快升 152.0.7977.75
  • Nacos 权限绕过漏洞 QVD-2026-59388:CVSS 9.8,一个请求直接接管配置中心
  • ServiceNow 漏洞:连续爆三个CVSS 评分满分 10.0
  • WordPress miniOrange SAML 插件 CVE-2026-15981:伪造 SAML 响应直取管理员权限,正在被扫描
  • DeepSeek Harness QVD‑2026‑57410 极危漏洞,Host 头伪造导致未授权 RCE

近期评论

  1. w 发表在 docker安装mysql

分类

  • AI (1)
  • java (1)
  • 建站 (2)
  • 数据库 (1)
  • 网络安全 (10)
  • 运维 (9)

    您可能错过了

    网络安全

    Chrome 高危沙箱逃逸 CVE-2026-84354:一个恶意网页就能在沙箱外执行代码,快升 152.0.7977.75

    wangjian@2
    作者 wangjian@2
    2026年9月3日
    QVD-2026-59388
    网络安全 java 运维

    Nacos 权限绕过漏洞 QVD-2026-59388:CVSS 9.8,一个请求直接接管配置中心

    wangjian@2
    作者 wangjian@2
    2026年9月1日
    网络安全

    ServiceNow 漏洞:连续爆三个CVSS 评分满分 10.0

    wangjian@2
    作者 wangjian@2
    2026年9月1日
    miniOrange SAML 2.0 Single Sign On WordPress 插件认证绕过漏洞
    网络安全 建站 运维

    WordPress miniOrange SAML 插件 CVE-2026-15981:伪造 SAML 响应直取管理员权限,正在被扫描

    wangjian@2
    作者 wangjian@2
    2026年8月28日
    DeepSeek Harness QVD‑2026‑57410漏洞,Host头伪造导致未授权RCE,AI Agent安全风险
    AI 网络安全 运维

    DeepSeek Harness QVD‑2026‑57410 极危漏洞,Host 头伪造导致未授权 RCE

    wangjian@2
    作者 wangjian@2
    2026年8月25日
    CVE‑2026‑19478 GitLab GraphQL高危未授权访问漏洞
    网络安全 运维

    CVE‑2026‑19478|GitLab GraphQL 高危漏洞,匿名请求即可删除公开项目

    wangjian@2
    作者 wangjian@2
    2026年8月20日
    BdThemes
    网络安全 建站

    BdThemes 供应链投毒攻击事件

    wangjian@2
    作者 wangjian@2
    2026年8月12日
    Docker MySQL 备份与恢复指南
    数据库 运维

    Docker MySQL 备份与恢复指南

    wangjian@2
    作者 wangjian@2
    2026年8月6日
    redis_logo
    网络安全 运维

    Redis 曝出多条零日 RCE 漏洞|Stream 双重释放与 RedisBloom 越界写入风险分析及防范方案

    wangjian@2
    作者 wangjian@2
    2026年7月27日
    7-Zip-Vulnerability-Code-Execution
    网络安全

    7-Zip存在高危漏洞CVE-2026-14266

    wangjian@2
    作者 wangjian@2
    2026年7月26日
    Copyright 2026 — 零海博客. All rights reserved.