You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

提交的SQL Server镜像挂载数据目录后丢失已提交变更求助

SQL Server镜像挂载数据目录后丢失已提交变更的问题

问题描述

我提交的SQL Server镜像在使用挂载时无法正常工作:未挂载时,镜像包含我所做的变更;但挂载数据目录后,无法看到已提交的变更。

复现步骤

  1. 运行SQL Server 2019容器:
docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=P@ssword123" -p 14350:1433 -d mcr.microsoft.com/mssql/server:2019-latest
  1. 连接该SQL Server并创建名为TestDB的数据库。
  2. 提交容器(ID为cabc3ac26dd0)并标记为testdb,随后删除原容器:
docker commit cabc3ac26dd0 testdb
docker container stop cabc3ac26dd0 
docker rm cabc3ac26dd0 
  1. 使用新镜像运行容器:
docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=P@ssword123" -p 14350:1433 -d testdb

连接该容器可看到TestDB,说明提交成功。
5. 删除容器后,将数据目录挂载到本地文件系统运行testdb镜像:

docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=P@ssword123" -p 14350:1433 --mount type=bind,source=C:\Users\me\testdbfiles\mssql\data,target=/var/opt/mssql/data -d testdb

此时连接容器看不到TestDB。

补充信息

  • 该docker run命令已使用数月,升级Docker Desktop 4.12.0后出现问题;
  • 挂载目录包含SQL Server数据库文件(如master.mdf),挂载语法正确;
  • 未挂载时查询sys.databases可见TestDB,挂载后无此数据库,说明master数据库不同;
  • 未挂载时/var/opt/mssql/data目录含TestDB文件,挂载后无;
  • 更新:镜像中新增的SQL Server登录,挂载后也无法看到,未挂载时正常。

排查与解决方法

核心原因

Docker的bind mount会直接将容器内的目标目录(/var/opt/mssql/data)替换为本地挂载目录的内容。你挂载的本地目录中的master.mdf是旧版本,未包含提交镜像时新增的TestDB和登录信息,因此容器启动后加载的是旧的master数据库,自然看不到变更。

排查步骤

  1. 检查本地挂载目录内容:直接查看C:\Users\me\testdbfiles\mssql\data,确认其中是否包含TestDB的相关文件(如TestDB.mdf、TestDB_log.ldf),以及master.mdf的修改时间是否与提交镜像的时间匹配。
  2. 验证容器内目录状态:启动挂载后的容器,执行以下命令查看数据目录内容:
docker exec -it <容器ID> bash
ls /var/opt/mssql/data

对比未挂载容器的/var/opt/mssql/data内容,确认挂载是否覆盖了镜像内的目录。
3. 检查权限问题:Docker Desktop 4.12.0可能调整了文件权限处理,确保本地目录的权限允许容器内的SQL Server进程(用户mssql)读取和写入文件。在Windows上,可检查目录的共享权限是否开放给Docker相关用户。

解决方法

方法1:同步本地挂载目录与镜像内容

将提交后镜像内的最新数据目录内容复制到本地挂载目录:

  1. 启动临时容器(不挂载本地目录):
docker run -d --name temp-sync testdb
  1. 复制容器内数据到本地目录:
docker cp temp-sync:/var/opt/mssql/data/ C:\Users\me\testdbfiles\mssql\data
  1. 停止并删除临时容器:
docker stop temp-sync && docker rm temp-sync
  1. 重新启动挂载容器,此时本地目录已包含最新的master数据库和TestDB文件。

方法2:改用Docker Volume管理数据

Docker Volume比bind mount更适合数据库场景,可避免手动同步的麻烦:

  1. 创建专用Volume:
docker volume create mssql-test-data
  1. 启动临时容器,将镜像内的数据同步到Volume:
docker run -d --name temp-volume-sync -v mssql-test-data:/var/opt/mssql/data testdb

等待容器启动完成后,停止并删除临时容器:

docker stop temp-volume-sync && docker rm temp-volume-sync
  1. 使用Volume启动容器:
docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=P@ssword123" -p 14350:1433 -v mssql-test-data:/var/opt/mssql/data -d testdb

内容的提问来源于stack exchange,提问作者Don Chambers

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 05:20:25