Docker化部署后 如何将旧版宿主机的MySQL数据映射迁移进去?

作者:袖梨 2026-07-13
必须先定位宿主机原MySQL的datadir路径(如/var/lib/mysql),停库后校验权限、版本兼容性及lower_case_table_names配置,再以绝对路径挂载到Docker容器的/var/lib/mysql,确保镜像版本不低于原版且属主匹配(如999:999)。

确认旧MySQL数据目录位置

必须先定位宿主机上原MySQL的datadir,否则后续挂载会失败。执行mysql --help | grep "datadir"或查看/etc/my.cnf中的datadir配置项。常见路径是/var/lib/mysql,但生产环境可能自定义为/data/mysql/opt/mysql/data。别直接假设路径——用mysqld --verbose --help | grep "datadir"验证更稳妥。

停库 + 权限与一致性校验

迁移前必须停止原MySQL服务:systemctl stop mysqld(或service mysql stop)。接着检查两件事:

  • datadir下所有文件属主是否为mysql:mysql(Docker内MySQL进程默认以mysql用户运行);若不是,宿主机上需chown -R mysql:mysql /path/to/old/datadir
  • 确认原MySQL版本(如mysqld --version),新Docker镜像版本不能低于旧版(例如旧版5.7,不可用8.0镜像直接挂载数据目录,会因ibdata1格式不兼容启动失败)
  • 检查my.cnflower_case_table_names值,Docker容器内外必须一致,否则表名识别异常

启动容器时正确挂载数据目录

不要用docker commitmysqldump导入——那是逻辑迁移,本文目标是物理目录映射。关键命令结构如下:

docker run -d   --name mysql-migrated   -p 3306:3306   -v /path/on/host:/var/lib/mysql   -e MYSQL_ROOT_PASSWORD=yourpass   -e TZ=Asia/Shanghai   mysql:5.7

注意三点:

  • /path/on/host必须是宿主机上原datadir的**绝对路径**,且该目录下应包含ibdata1ib_logfile*mysqlperformance_schema等原始文件夹/文件
  • 务必指定与原环境一致的镜像标签(如mysql:5.7),避免版本越级
  • 如果原MySQL启用了SSL或自定义socket路径,需同步挂载/etc/mysql/conf.d//var/run/mysqld等配套目录,否则容器可能报错退出

启动失败时最常卡在哪几个点

容器反复重启或docker logs mysql-migrated显示Can't start server : Bind on unix socketInnoDB: Unable to lock ./ibdata1,大概率是以下原因:

  • ibdata1被原MySQL进程残留锁住:确认systemctl is-active mysqld返回inactive,再lsof /path/to/old/datadir/ibdata1清空占用
  • 权限不对:进入容器docker exec -it mysql-migrated ls -l /var/lib/mysql,看文件属主是否为999:999(MySQL 5.7官方镜像默认uid/gid);若宿主机原目录属主是27:27,需提前chown -R 999:999 /path/on/host
  • SELinux启用:CentOS/RHEL上执行setenforce 0临时关闭,或chcon -Rt svirt_sandbox_file_t /path/on/host

物理目录迁移本质是复用InnoDB存储引擎的原始文件,任何一点元数据不匹配都会导致启动失败——它不像SQL导入那样容错,必须严格对齐版本、权限、配置三要素。

相关文章

精彩推荐