Docker容器中修改MDF/LDF文件UID&GID失败,无法附加SQL数据库
问题描述
要在Azure Data Studio中打开test.mdf和testlog.ldf,将文件复制到Docker容器后执行附加数据库操作失败,具体操作及错误如下:
复制文件到容器的操作
docker stop NameContainer docker cp /Users/user/Downloads/NameFile/test.mdf NameContainer:/var/opt/mssql/data/ docker cp /Users/user/Downloads/NameFile/testlog.ldf NameContainer:/var/opt/mssql/data/ docker start NameContainer
附加数据库的SQL语句
CREATE DATABASE Testing ON (FILENAME = '/var/opt/mssql/data/test.mdf'), (FILENAME = '/var/opt/mssql/data/testlog.ldf') FOR ATTACH;
错误提示
Msg 3415, Level 16, State 2, Line 1
Database 'Testing' cannot be upgraded because it is read-only, has read-only files or the user does not have permissions to modify some of the files. Make the database or files writeable, and rerun recovery.
文件权限检查结果
执行ls -l查看容器内文件权限,发现复制的文件所有者与SQL Server默认文件不符:
-rwxr-xr-x 1 501 dialout 4194304 Nov 2 2008 test.mdf -rwxr-xr-x 1 501 dialout 1048576 Nov 2 2008 testlog.ldf -rw-r----- 1 mssql root 4653056 Feb 24 10:56 master.mdf -rw-r----- 1 mssql root 2097152 Feb 24 11:19 mastlog.ldf
尝试修改所有者的操作(未生效)
docker exec -i -t NameContainer /bin/bash cd /var/opt/mssql/data/ ls -l chown -f mssql:root /var/opt/var/opt/mssql/data/test.mdf chown -f mssql:root /var/opt/var/opt/mssql/data/testlog.ldf
问题根源
- 路径错误:执行
chown时使用了重复的/var/opt/路径,正确路径应为/var/opt/mssql/data/test.mdf,而非/var/opt/var/opt/mssql/data/test.mdf,导致命令实际未作用到目标文件。 - 文件权限不匹配:复制后的文件权限是
-rwxr-xr-x,而SQL Server默认文件权限为-rw-r-----(仅所有者有读写权限),权限过宽也可能引发读写权限校验失败。
解决步骤
步骤1:修正所有者修改命令
进入容器后,使用正确路径执行chown:
docker exec -it NameContainer /bin/bash cd /var/opt/mssql/data/ # 修改所有者为mssql:root chown mssql:root test.mdf testlog.ldf # 验证修改结果 ls -l test.mdf testlog.ldf
步骤2:修正文件权限
将文件权限调整为与SQL Server默认文件一致:
chmod 640 test.mdf testlog.ldf
步骤3:重新附加数据库
重启容器后,再次执行附加语句:
docker restart NameContainer
然后在Azure Data Studio中重新运行:
CREATE DATABASE Testing ON (FILENAME = '/var/opt/mssql/data/test.mdf'), (FILENAME = '/var/opt/mssql/data/testlog.ldf') FOR ATTACH;
可选:复制文件时直接指定所有者(更高效)
在使用docker cp复制文件时,可通过临时容器中转,直接设置文件所有者和权限,避免后续修改:
docker stop NameContainer # 创建临时容器,挂载目标目录与本地文件目录,完成复制、权限设置 docker run --rm -v NameContainer:/var/opt/mssql/data -v /Users/user/Downloads/NameFile:/source alpine \ sh -c "cp /source/test.mdf /source/testlog.ldf /var/opt/mssql/data/ && chown mssql:root /var/opt/mssql/data/test.mdf /var/opt/mssql/data/testlog.ldf && chmod 640 /var/opt/mssql/data/test.mdf /var/opt/mssql/data/testlog.ldf" docker start NameContainer
内容的提问来源于stack exchange,提问作者molik
相关产品推荐
相关产品推荐

