在日常开发和运维中,我们经常需要把 Docker 容器中的 MySQL 数据迁移到另一个容器或则其他mysql服务器。无论是升级数据库版本、更换宿主机,还是做环境复制,使用 mysqldump 进行逻辑备份恢复是最通用、最安全的方式。
⚠️ 版本兼容提示:源和目标 MySQL 的大版本应一致(如都是 5.7 或 8.0),小版本越接近越好,否则导入时可能遇到 SQL 语法或存储引擎不兼容的问题。
环境准备:
假设你已有两个 MySQL 容器:
- 源容器:mysql_source
- 目标容器:mysql_target(已经运行,但可能是空的,或者已有部分数据)
两个容器都使用 root 用户,密码均为 123(请根据实际情况替换)。
一、迁移所有数据库(全量迁移)
适用场景:完整克隆一个 MySQL 实例,包括用户权限、系统库(mysql、sys等)。
1.1 在宿主机执行
docker exec mysql_source mysqldump -u root -p123 --all-databases > all_dbs.sql--all-databases:导出所有库,包括 mysql、information_schema、performance_schema(但后两个通常恢复时会被跳过或重建,无影响)。
1.2 导入到目标容器
cat all_dbs.sql | docker exec -i mysql_target mysql -u root -p123-i参数必不可少,它允许将标准输入重定向到容器的 MySQL 客户端
二、只迁移指定的一个或多个数据库(手动创建数据库)
适用场景:你只需要迁移 myapp_db 或 其他指定多个库,而不影响目标容器中的其他库。该方式需要手动提前创建数据库后才能导入数据,如果想自动创建数据库,查看下方第三节内容。
2.1 导出指定库(不包含 CREATE DATABASE)
导出 myapp_db(多个库时,空格分割,会将所有库都导出到一个sql文件中)
docker exec mysql_source mysqldump -u root -p123 myapp_db > myapp_db.sql- 导出的文件不会包含 CREATE DATABASE 语句,只包含表结构和数据。
2.2 导入前先手动创建数据库
在目标容器中建库(字符集建议与源一致),如果有多个库需要都把库创建好:
docker exec -i mysql_target mysql -u root -p123 -e "CREATE DATABASE IF NOT EXISTS myapp_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"2.3 导入数据
cat myapp_db.sql | docker exec -i mysql_target mysql -u root -p123- 此时 MySQL 客户端默认连接到 mysql 库,但 SQL 文件中包含 USE myapp_db; 等语句,因此会正确写入对应的库。
三、迁移时自动创建数据库(无需手动建库)
适用场景:你想让 SQL 文件自己负责建库,导入时更省事。适合迁移单个或多个库,且目标环境允许创建新库。
3.1 导出时使用 –databases 参数
导出 myapp_db 和 order_db
docker exec mysql_source mysqldump -u root -p123 --databases myapp_db order_db > auto_create_dbs.sql- 关键点:–databases(复数)会使 mysqldump 在输出文件中为每个库生成 CREATE DATABASE IF NOT EXISTS 和 USE 语句。
直接导入,无需手动建库
cat auto_create_dbs.sql | docker exec -i mysql_target mysql -u root -p123四、补充:迁移包含存储过程/触发器
如果你的数据库使用了存储过程、函数或触发器,导出时请加上 –routines –triggers:
docker exec mysql_source mysqldump -u root -p123 --databases myapp_db --routines --triggers > myapp_db_full.sql后续导入命令不变。


