在适用于 Windows 的 Docker 上并使用 windows 容器,我无法让我的持久卷在 Windows 容器的主数据库目录上工作。这将是
C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\DATA
如何获得数据库持久卷的优势,而不必搞乱备份和恢复到 mssql-server-container 中?
这可能是因为数据目录中存储了主数据库和系统数据库,我尝试在该文件夹中挂载持久卷。
在适用于 Linux 容器的 SQL Server 中,这很简单,您可以将持久卷连接到
/var/opt/mssql
并使数据库持久化。
我知道我可以将数据库从备份恢复到容器中,但这有两个主要缺点:我必须有一个大的容器,因为我正在使用一个大数据库。因此,我将容器的 20 GB 限制扩展到 60 GB,但是...每次从备份重建数据库非常耗时。 第二个缺点是,如果 mssql-dev 容器被终止,数据库也会丢失。此数据库上的任何工作都会消失。如果数据库可以驻留在持久卷上,情况会有所不同。
docker run -d -e sa_password=<Password> -e ACCEPT_EULA=Y -v "C:\mylocalfolder:C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\DATA" microsoft/mssql-server-windows-developer
错误消息为“Windows 系统调用失败:虚拟计算机或容器意外关闭”。 (0xc0370106)
将持久卷连接到另一个位置,例如
c:\mydata
以防止上面的错误消息。
然后在不使用标准数据库文件夹的情况下将数据库连接到服务器。
提取数据库.bak文件,所以有mdf和日志文件
--Get the name of your DB
RESTORE FILELISTONLY
FROM DISK = 'c:\mydata'
GO
--do the extraction of the bak file to certain folder
RESTORE DATABASE mydatabase
FROM DISK = 'c:\mydata'
WITH REPLACE,
MOVE 'mydatabase' TO 'c:\mydata\extractedDb.mdf',
MOVE 'mydatabase_log' TO 'c:\mydata\extractedLog.ldf'
GO
完成此操作后,您现在应该在持久卷上准备好数据库文件。现在将数据库附加到服务器。这必须通过创建一个新的数据库来完成但此过程只需要纳秒即可完成!
CREATE DATABASE StackoverflowIsGreat
ON (FILENAME = 'c:\mydata\extractedDb.mdf'),
(FILENAME = 'c:\mydata\extractedLog.ldf')
FOR ATTACH;
现在数据库在持久卷中是安全的。如果 db-server 容器出现故障或正在重建,您只需再次运行最后一条语句(或者更好地在 docker-compose 或 dockerfile 中实现它):
CREATE DATABASE StackoverflowIsGreat
ON (FILENAME = 'c:\mydata\extractedDb.mdf'),
(FILENAME = 'c:\mydata\extractedLog.ldf')
FOR ATTACH;
-attach_dbs 参数似乎以同样的方式工作。 Docker 运行:
docker run -p 1433:1433 --name mssql-dev -e sa_password=<yourpassword> -e ACCEPT_EULA=Y -e attach_dbs="[{'dbName':'PowerSlide_SQLDB','dbFiles':['C:\\your\\path\\database.mdf','C:\\sqldata\\databaselog.ldf']}]" -v "d:\sqldata:C:\sqldata" microsoft/mssql-server-windows-developer
或者如果您更喜欢 Docker-Compose,这有点棘手。我必须省略括号外的前导和结束
'
并用 '
替换括号内的双引号才能使其正常工作。
version: '3.2'
services:
mssql-dev:
container_name: mssql-dev
image: 'microsoft/mssql-server-windows-developer'
volumes:
- "d:\\sqldata:C:\\sqldata"
ports:
- "1433:1433"
restart: always
environment:
- "ACCEPT_EULA=Y"
- "sa_password=yourpassword"
- attach_dbs=[{"dbName":"<yourDbName>","dbFiles":["C:\\<your>\\path\\database.mdf","C:\\your\\path\\databaselog.ldf"]}]
volumes:
mssql-dev-data:
看来这个问题可以用上面的解决方法1和2来回答。
--Get the name of your DB
RESTORE FILELISTONLY
FROM DISK = 'c:\mydata'
GO
--do the extraction of the bak file to certain folder
RESTORE DATABASE mydatabase
FROM DISK = 'c:\mydata'
WITH REPLACE,
MOVE 'mydatabase' TO 'c:\mydata\extractedDb.mdf',
MOVE 'mydatabase_log' TO 'c:\mydata\extractedLog.ldf'
GO
Docker 运行示例:
docker run -p 1433:1433 --name mssql-dev -e sa_password=<yourpassword> -e ACCEPT_EULA=Y -e attach_dbs="[{'dbName':'PowerSlide_SQLDB','dbFiles':['C:\\your\\path\\database.mdf','C:\\sqldata\\databaselog.ldf']}]" -v "d:\sqldata:C:\sqldata" microsoft/mssql-server-windows-developer
如果您更喜欢 Docker-Compose,那就有点棘手了。我必须省略括号外的前导和结束
'
并用 '
替换括号内的双引号才能使其正常工作。 docker-compose 的示例:
version: '3.2'
services:
mssql-dev:
container_name: mssql-dev
image: 'microsoft/mssql-server-windows-developer'
volumes:
- "d:\\sqldata:C:\\sqldata"
ports:
- "1433:1433"
restart: always
environment:
- "ACCEPT_EULA=Y"
- "sa_password=yourpassword"
- attach_dbs=[{"dbName":"<yourDbName>","dbFiles":["C:\\<your>\\path\\database.mdf","C:\\your\\path\\databaselog.ldf"]}]
volumes:
mssql-dev-data:
或使用 SQL 命令附加数据库
CREATE DATABASE StackoverflowIsGreat
ON (FILENAME = 'c:\mydata\extractedDb.mdf'),
(FILENAME = 'c:\mydata\extractedLog.ldf')
FOR ATTACH;
您应该尽量避免将 MSSQL 数据库文件移动到 c:\drive 的子目录中。
主要是因为:我必须有一个大的容器尺寸,因为我 正在使用一个大数据库。所以我延长了20GB的限制 容器到 60 GB 但...
如果在 AKS 中运行,容器映像大小为 20GB,且无法更改。即使您将持久存储映射到 C: 中的子文件夹,MSSQL Server 也不会正确进行空间计算,并且即使数据库中有足够的空间,也不会让您恢复数据库。