在上一篇文章中我们已经成功在docker中跑起来了一个sql server。
现在问题来了,我有一个mdf文件,我应该如何导入到sql server?
在window平台似乎有对应的工具,但是docker中却不一样。原因是docker相当于创建了一个虚拟的linux环境,在这个环境中运行sql server。作为mac玩家,我们没有类似于window这样的工具。即使有,由于sql server运行在虚拟的环境中,而我们的文件在本地主机中,所以两个是互相隔离的。
简单来说,如果你想要导入mdf文件,你应该看到有人告诉你这样做:
EXEC sp_attach_db @dbname = '你的数据库名',
@filename1 = 'mdf文件路径(包缀名)',
@filename2 = 'Ldf文件路径(包缀名)'
但是当你在你的sql server中输入上面的语句,他会告诉你路径不存在。为什么?因为sql server运行在docker提供的虚拟linux上,在那个linux上显然没有你这个文件。
解决方法:
我在https://docs.microsoft.com/zh-cn/sql/linux/sql-server-linux-configure-docker?view=sql-server-2017中找到了解决方案。
简单来说,docker就是一个容器,而我们的数据库文件mdf现在在容器外,我们需要将这个文件放入容器内,才能进行导入。
sql server提供了一种方法叫做:将主机目录加载为数据卷,简单来说就是把我们主机上的一个目录映射到容器内的一个目录上。
然而微软之后又叫了一条提醒,暂时不支持将mac的主机目录加载进去,它提示我们改为使用数据卷。
指令如下:
docker run -e 'ACCEPT_EULA=Y' -e 'MSSQL_SA_PASSWORD=<YourStrong!Passw0rd>' -p 1433:1433 -v sqlvolume:/var/opt/mssql -d mcr.microsoft.com/mssql/server:2017-latest
注意看:这个指令其实是在创建一个sql server 然后这个sql server多了-v sqlvolume:/var/opt/mssql 这一部分, 用于为这个sql server创建一个volume名为sqlvolume,并且这个容器的位置在docker虚拟的linux的/var/opt/mssql中。 如果我们还想为这个数据库命名 我们需要在-p 1433:1433 后面加上一句 --name yourname (如果直接加在最后面会报错)
好了现在我们已经创建了一个带有数据卷的sql server。我们可以使用 docker volume ls 查看是否创建成功,应该会显示一个volume。
类似
DRIVER VOLUME NAME
local demovolume
demovolume是我给我的volume取得名字。
ok 现在我们只需要将mdf文件拷贝到容器中再导入即可,指令如下:
docker cp <Host path> <Container ID>:<Container path>
container id可以通过 docker ps查看到。
像我这样:
docker cp /yourpath.../DemoHis_log.ldf b2e95c59a4fb:/var/opt/mssql/DemoHis_log.ldf
docker cp /yourpath.../DemoHis.mdf
现在我们在var/opt/mssql/中已经有这两个文件了了只需要在数据库中输入语句
EXEC sp_attach_db @dbname = 'DemoHis',
@filename1 = '/var/opt/mssql/DemoHis.mdf',
@filename2 = '/var/opt/mssql/DemoHis_log.ldf'
GO
就会提示运行成功,至此我们终于将mdf文件导入了docker中的sql server。
后记:
虽然写的很多很杂,但是还是要写,一方面自己没有太多时间去写的很好看,但是另外一方面这个问题在网上又没有找到别的解决方法。网上的博客中都是泛泛而谈,装环境的博客千千万,装完环境之后能不能用倒是没人关心了。hello world之后的第二步,也是需要开拓的。
mac 下使用sql server的坑实在多,为了导入一个mdf文件就要这样费神,只能留下一篇这样的流水记,勉励探索的后人。