在使用 Docker 部署 MySQL 的场景中,经常会遇到这样的需求:
一次性导出容器内除系统库以外的所有数据库 ,并分别生成 .sql 文件,用于备份或迁移。
本文介绍一种无需进入交互式容器 、通过一条 docker exec 命令,在容器内生成并执行导出脚本的实现方式。
一、整体思路
实现流程如下:
- 通过
docker exec在 MySQL 容器中执行 Bash - 动态创建一个数据库导出脚本
export_dbs.sh - 使用
mysql命令获取所有数据库列表 - 过滤掉系统数据库
- 循环调用
mysqldump,将每个数据库导出为独立的.sql文件 - 将导出文件保存到容器内
/tmp目录
二、完整命令示例
bash
docker exec -it mysql-container bash -c "cat << 'EOF' > /tmp/export_dbs.sh
#!/bin/bash
PASSWORD=\"root\"
mysql -uroot -p\${PASSWORD} --socket=/var/run/mysqld/mysqld.sock -e \"SHOW DATABASES;\" | \
grep -v \"Database\" | \
grep -v \"information_schema\" | \
grep -v \"mysql\" | \
grep -v \"performance_schema\" | \
grep -v \"sys\" | \
while read db; do
echo \"Exporting database: \$db\"
mysqldump -uroot -p\${PASSWORD} \
--socket=/var/run/mysqld/mysqld.sock \
--databases \"\$db\" > \"/tmp/\$db.sql\"
done
echo \"Export completed.\"
EOF
chmod +x /tmp/export_dbs.sh
/tmp/export_dbs.sh"
三、关键部分详解
1. docker exec 执行容器内命令
bash
docker exec -it mysql-container bash -c "..."
mysql-container:MySQL 容器名称bash -c:在容器中执行一段 Bash 命令-it:支持交互与终端输出
2. 使用 Here Document 生成脚本
bash
cat << 'EOF' > /tmp/export_dbs.sh
- 使用 Here Document 写入多行脚本
'EOF'使用单引号可避免变量在宿主机侧被提前展开- 脚本被写入容器内
/tmp/export_dbs.sh
3. MySQL 认证方式
bash
PASSWORD="root"
mysql -uroot -p${PASSWORD} --socket=/var/run/mysqld/mysqld.sock
- 使用 root 用户连接
- 通过 Unix Socket 连接 MySQL(适用于官方 MySQL Docker 镜像)
- 避免 TCP 连接带来的端口问题
4. 获取并过滤数据库列表
bash
SHOW DATABASES;
配合 grep -v 过滤系统数据库:
information_schemamysqlperformance_schemasys
最终只保留业务数据库。
5. 循环导出数据库
bash
while read db; do
mysqldump --databases "$db" > "/tmp/$db.sql"
done
特点:
- 每个数据库生成一个独立的 SQL 文件
- 文件命名规则:
数据库名.sql - 便于单库恢复与管理
四、导出结果说明
导出完成后:
-
SQL 文件位于容器内:
text/tmp/*.sql
如需拷贝到宿主机,可使用:
bash
docker cp mysql-container:/tmp/dbname.sql .
或批量拷贝整个目录。
五、适用场景
✔ MySQL Docker 容器备份
✔ 数据迁移前批量导出
✔ CI / 自动化备份脚本
✔ 测试环境数据库快照
六、注意事项
- ❗ 不建议在生产环境明文写密码(可改用
.my.cnf) - ❗ 大库导出时注意磁盘空间
- ❗ 可根据需要添加
--single-transaction以减少锁表
七、总结
通过一条 docker exec 命令,我们实现了:
- 在容器内动态生成脚本
- 自动过滤系统数据库
- 批量导出所有业务库
- 无需手动进入容器操作