首页 > 解决方案 > SQLServer Docker:如何备份和恢复数据 *volume*?

问题描述

我有一个使用 docker-compose 运行的 MS SQLServer 2017 Linux Docker 容器。docker-compose up / down (在 Windows 主机上工作。)服务器正在运行,我添加了数据,并且由于服务器使用docker volume,这些数据在多个之间是持久的。使用时数据消失docker-compose down -v。所以这按预期工作:

services:
    sql:
        image: mcr.microsoft.com/mssql/server:2017-GA-ubuntu
        volumes:
         - sqldata:/var/opt/mssql
        ...

volumes:
    sqldata:
        driver: local
        name: sqldata

现在我正在尝试备份和恢复数据库。我知道直接使用 SQLServer 的“正常”方式。这有效:

# Restore a backup inside the container volume
docker exec -it sql mkdir /var/opt/mssql/backup
docker cp .\Test.bak sql:/var/opt/mssql/backup
sqlcmd -S 127.0.0.1,1433 -U sa -P Secr3tSA_Passw0rd -H 127.0.0.1,1433 -Q "RESTORE DATABASE [Test] FROM DISK='/var/opt/mssql/backup/Test.bak' WITH REPLACE"

# Backup a database inside the container volume, then copy to local file
docker exec sql rm -rf /var/opt/mssql/backup/Test.bak
sqlcmd -S 127.0.0.1,1433 -U sa -P Secr3tSA_Passw0rd -H 127.0.0.1,1433 -Q "BACKUP DATABASE [Test] TO DISK='/var/opt/mssql/backup/Test.bak'"
docker cp sql:/var/opt/mssql/backup/Test.bak .\Test.bak

现在我在想,也许有比将 SA 密码放入 BAT 文件并将其交给我的客户和服务技术人员更好的方法。只需获取该卷的副本即可解决问题!

我找到了这个:

# Make sure the SQLServer is not writing/blocking any files.
docker-compose stop sql

# Backup & Restore the sqldata volume.
docker run --rm -v sqldata -v $pwd\backup:/backup ubuntu bash -c "cd /whsqldata && tar xvf /backup/backup.tar --strip 1"
docker run --rm -v sqldata -v $pwd\backup:/backup ubuntu bash -c "cd /whsqldata && tar cvf /backup/backup.tar ."

# Restart the SQLServer.
docker-compose start sql

这会在我的用户目录中创建预期的 backup.tar ......但它非常小!并且还原后,SQLServer 无法连接到数据库。看起来 backup.tar 没有内容。 但仔细观察,我的 sqldata 卷也是如此!是空的!?当我启动一个挂载同一卷的 bash 时,我可以看到该目录,但其中没有任何内容:

docker run --rm -v sqldata -it ubuntu
/ # ls sqldata/ -a
. ..
/ #

SQLServer 的数据仍然存在。所以它必须被保存在某个地方,对吧?我错过了什么?!

标签: sql-serverdockerdocker-composedocker-volume

解决方案


好的,在阅读了我应该如何备份和恢复 docker 命名卷的答案后,我发现我的错误在于我如何安装卷。而不是-v sqldata我必须写-v sqldata:/sqldata. 还更改了我的命令中的一些路径。

完成的命令是:

# Backup the data volume
docker run --rm \
       -v sqldata:/sqldata \
       -v $pwd\:/backup \
       ubuntu tar cvf /backup/backup.tar /sqldata

# Remove existing data volume (clear up old data, if exists)
docker volume rm sqldata

# Restore the data volume
docker run --rm \
       -v sqldata:/sqldata \
       -v $pwd\:/backup \
       ubuntu tar xvf /backup/backup.tar -C sqldata --strip 1

推荐阅读