如何使Mac Docker支持SQL on Linux容器Volume特性
問題引入
這天老鳥火急火燎的找到菜鳥:“鳥兒啊,按照你之前的文章SQL on Linux Run on Docker,當我銷毀SQL on Linux Docker容器以后,我容器中的所有數據庫數據丟失啦,怎么辦,怎么辦啊?”。
菜鳥一臉懵逼:“我是參照微軟官方文檔來的啊?難道這幫XX連這個問題都沒有想到?”。于是,菜鳥開始了問題的重現和解決方法。
問題重現
按照上一篇文件啟動的Docker容器,SQL on Linux實例中的數據庫文件真的會隨著Docker容器的銷毀而消失,造成數據丟失的災難嗎?這一節進行問題重現和復盤。
啟動Docker容器
使用Docker Run命令啟動SQL on Linux服務,映射到母體機41433端口上。
$ docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=SQLOnLinux@123' -p 41433:1433 -d microsoft/mssql-server-linux創建測試對象
使用SSMS連接到Docker母體機41433端口上,執行下面的測試代碼:創建測試數據庫、創建測試表、初始化兩條數據和查詢測試表。
IF DB_ID('TestDb') IS NULL ? ?CREATE DATABASE TestDb; GOUSE TestDbGOIF OBJECT_ID('dbo.Test', 'U') IS NOT NULLDROP TABLE dbo.TestGOCREATE TABLE dbo.Test(RowID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY,Name VARCHAR(20) NOT NULL);INSERT INTO dbo.TestSELECT 'A' UNION ALL SELECT 'B';SELECT * FROM dbo.Test;結果如下圖展示:
銷毀Docker容器
接下來模擬Docker容器銷毀過程:我們需要使用Docker Stop停止SQL on Linux容器,然后使用Docker rm刪除這個容器,接下來再次啟動Docker容器,最后檢查測試數據庫、測試表和數據是否存在。如果不存在,說明Docker容器中的數據已經丟失。
$ docker ps CONTAINER ID ? ? ? ?IMAGE ? ? ? ? ? ? ? ? ? ? ? ? ?COMMAND ? ? ? ? ? ? ? ? ?CREATED ? ? ? ? ? ? STATUS ? ? ? ? ? ? ?PORTS ? ? ? ? ? ? ? ? ? ? NAMES8c1202ff7a33 ? ? ? ?microsoft/mssql-server-linux ? "/bin/sh -c /opt/m..." ? 2 minutes ago ? ? ? Up 2 minutes ? ? ? ?0.0.0.0:41433->1433/tcp ? suspicious_liskov ... $ docker stop 8c1202ff7a338c1202ff7a33 $ docker rm 8c1202ff7a338c1202ff7a33 $ docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=SQLOnLinux@123' -p 41433:1433 -d microsoft/mssql-server-linux83cd4ca5cdf3d370118c10d8b783b204f86aa7b50fd7e334a27542d2cf7a1230檢查測試對象
再次使用SSMS連接到Docker母體機41433端口,查看測試數據庫,展示如下圖:
從這個結果來看,測試數據庫已經丟失。說明Docker容器與容器中的數據庫是命運共同體、同生死共命運。如果Docker容器銷毀,容器中的數據庫數據也隨之丟失。這個是用戶數據的災難,我們需要迫切解決這個問題。看來老鳥說的大實話啊。
解決問題
SQL on Linux對Mac Docker Volume的限制
要解決這個問題,我們需要引入Docker的Volume技術。簡單的說,這個技術的核心思想就是在啟動Docker容器的時候,將Docker容器中的目錄映射到母體機的目錄,Docker容器對這個目錄的所有操作會反映到母體機的這個映射目錄里面。當Docker容器銷毀的時候,母體機的這個映射目錄會被保留下來。這樣,我們的數據庫數據文件不會隨著容器的銷毀而消失了,繼而就解決了這個問題。但是,偏偏目前SQL on Linux不支持Mac操作系統的Docker Volume特性。詳情參見微軟官方文檔:Run the SQL Server Docker image on Linux, Mac, or Windows
關鍵的地方,截圖如下展示:
Mac系統Docker就真的不支持SQL on Linux Docker容器的Volume嗎?讓我們來試試看:
的確啟動Docker容器的過程中就會報告錯誤,詳細的錯誤日志信息如下:
$ cat ~/Downloads/linuxsqldata/log/errorlog 2017-02-09 13:20:06.62 Server ? ? ?Microsoft SQL Server vNext (CTP1.2) - 14.0.200.24 (X64) Jan 10 2017 19:15:28 Copyright (C) 2016 Microsoft Corporation. All rights reserved.on Linux (Ubuntu 16.04.1 LTS) 2017-02-09 13:20:06.76 Server ? ? ?UTC adjustment: 0:00 2017-02-09 13:20:06.80 Server ? ? ?(c) Microsoft Corporation. 2017-02-09 13:20:06.84 Server ? ? ?All rights reserved. 2017-02-09 13:20:06.88 Server ? ? ?Server process ID is 4116. 2017-02-09 13:20:06.92 Server ? ? ?Logging SQL Server messages in file 'C:\var\opt\mssql\log\errorlog'. 2017-02-09 13:20:06.98 Server ? ? ?Registry startup parameters: -d C:\var\opt\mssql\data\master.mdf-l C:\var\opt\mssql\data\mastlog.ldf-e C:\var\opt\mssql\log\errorlog 2017-02-09 13:20:07.09 Server ? ? ?Command Line Startup Parameters:--setup--sa-password 2017-02-09 13:20:07.58 Server ? ? ?Error: 17113, Severity: 16, State: 1. 2017-02-09 13:20:07.58 Server ? ? ?Error 87(The parameter is incorrect.) occurred while opening file 'C:\var\opt\mssql\data\master.mdf' to obtain configuration information at startup. An invalid startup option might have caused the error. Verify your startup options, and correct or remove them if necessary.解決方案
巴嘎,這里就又引入了另外一個問題,如何解決Mac系統上SQL on Linux的Docker容器不支持Volume的問題?不要驚慌,淡定,當然是有辦法的,這個解決方法便是這篇文章存在的意義。解決方法如下:
$ docker create -v /var/opt/mssql --name sql41433data microsoft/mssql-server-linux2e1deac3c2bffa5f6cd97dfdc3683c59628538550ea9010d16214906c299cf54$ docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=SQLOnLinux@123' -p 41433:1433 --volumes-from sql41433data -it --name linuxsql41433 microsoft/mssql-server-linux大概30秒后,Docker容器中的SQL實例服務起來以后,首先,參照問題重現中創建測試對象,然后銷毀Docker容器,接下來再次啟動Docker容器。
$ docker ps CONTAINER ID ? ? ? ?IMAGE ? ? ? ? ? ? ? ? ? ? ? ? ?COMMAND ? ? ? ? ? ? ? ? ?CREATED ? ? ? ? ? ? STATUS ? ? ? ? ? ? ?PORTS ? ? ? ? ? ? ? ? ? ? NAMES596f3bfebb8a ? ? ? ?microsoft/mssql-server-linux ? "/bin/sh -c /opt/m..." ? 57 seconds ago ? ? ?Up 56 seconds ? ? ? 0.0.0.0:41433->1433/tcp ? linuxsql41433 ... $ docker stop 596f3bfebb8a596f3bfebb8a $ docker rm 596f3bfebb8a596f3bfebb8a $ docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=SQLOnLinux@123' -p 41433:1433 --volumes-from sql41433data -it --name linuxsql41433 microsoft/mssql-server-linux最后檢查測試對象,截圖如下:
其實,從啟動過程的日志,我們也可以看到TestDb已經啟動。
說明這個解決方法切實有效。
最后總結
這篇文章解決了Docker容器中SQL on Linux實例數據庫與容器本身同生死同命運的問題,使得用戶數據在容器被銷毀時得以保留。更加詳細的過程和步驟,可以參看youku視頻:http://v.youku.com/v_show/id_XMjUwNDE5MTA3Mg==.html
相關文章:?
SQL Server 急救包(First Responder Kit)入門教程
SQL Server on Linux 理由淺析
SQLServer On Linux Package List on CentOS
SQL Server on Linux的文件和目錄結構
個性化配置你的SQL Server on Linux
SQL on Linux Run on Docker
原文地址:https://yq.aliyun.com/articles/69517
.NET社區新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注
總結
以上是生活随笔為你收集整理的如何使Mac Docker支持SQL on Linux容器Volume特性的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Xamarin的坑 - 绑定(二) -
- 下一篇: 迁移数据库到SQL on Linux D