NLEN
Direct technisch advies?
Home > Blog

SQL Server draaien op Docker deel 2 Backup en Restore

Taco Zoetemelk 06-01-2020 2:50 PM
Categories: BLOG, Cloud, DBMS, MS SQL Server, Technisch

In het eerste deel van deze serie van twee legden we uit hoe SQL Server op Docker gedraaid kan worden. Het eindresultaat was een Docker-container en een storage volume met daarin een SQL Server instance. In deze blog gaat Taco Zoetemelk verder werken met deze Docker-container en laat hij zien hoe je een back-up maakt en terugzet.

Om de instance te beheren, was het zelfs mogelijk om met Management Studio te verbinden aan de SQL Server instance. Ik ga verder werken met deze Docker-container, dus als je de acties in deze blog wil uitproberen, raad ik je aan om eerst de stappen uit deel 1 uit te voeren. Alle acties worden uitgevoerd vanuit Docker shell, dus niet via Management Studio.

Huidige situatie

Voorbereidingen

Ik begin met het starten van de container. Als deze nog niet draait, doe dan eerst het volgende:
Controleren wat er nu draait:

$ docker ps

Controleren welke containers er beschikbaar zijn om te starten:

$ docker ps -a

Controleren of het volume beschikbaar is:

$ docker volume ls

Starten van de docker container

$ docker start some-mssql

Controleren of de container goed gestart is:

$ docker ps

Controleren of de eerder aangemaakte database nog bestaat en of er nog records in de aangemaakte tabel staan:

$ docker exec -it some-mssql /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P VeryStrongPassword@2019 -d DockerTest -Q "select count(*) from DockerTestTable"

Leegmaken test tabel en vullen met iets meer data

docker exec -it some-mssql /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P VeryStrongPassword@2019 -d DockerTest -Q "declare @num int; set @num =1; while @num < 10001 begin; insert into [DockerTest].[dbo].[DockerTestTable] values (@num, 'Testdata ' + cast(@num as nvarchar) ); set @num = @num + 1 ; end ;"

Aanmaken backup directory op het storage volume, zodat ook de backups beschikbaar blijven, in het geval dat de container stopt.

docker exec -it some-mssql /bin/mkdir -p /var/opt/mssql/sql_backup

Back-up maken

Back-ups kunnen worden gemaakt worden met de reguliere back-upcommando's, net zoals queries gedraaid kunnen worden met de sqlcmd tool. Ik begin met een simpele full back-up naar de eerder aangemaakte back-updirectory.

$ docker exec -it some-mssql /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P VeryStrongPassword@2019 -d DockerTest -Q "BACKUP DATABASE [DockerTest] TO DISK = N'/var/opt/mssql/sql_backup/DockerTest_Full.bak' WITH NOFORMAT, NOINIT, NAME = N'DockerTest-Full Database Backup', COMPRESSION, STATS = 10"

Wanneer je regelmatig met SQL Server werkt, zal je zien dat het backup commando niet anders is als wanneer je het vanuit Management Studio zou doen in T/SQL.

Als ik kijk in de aangemaakte backup directory, zal je zien dat daar nu een backup file is aangemaakt.

$ docker exec -it some-mssql /bin/ls -hl /var/opt/mssql/sql_backup

Restore

Allereerst verwijder ik wat (random) data uit de tabel, om een gebruikersfout te simuleren. Met deze query worden 500 random nummers gegenereerd en het record met dat id wordt verwijderd.

$ docker exec -it some-mssql /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P VeryStrongPassword@2019 -d DockerTest -Q " declare @num int; set @num =1; while @num < 500 begin; delete from [DockerTest].[dbo].[DockerTestTable] where id = (SELECT CAST(RAND()*10000 AS INT)); set @num = @num + 1 ; end ;"


...

Als ik dan kijk in de tabel zijn er nog maar 9.516 records in de tabel aanwezig (aantallen kunnen verschillen, omdat random nummers vaker kunnen voorkomen)

$ docker exec -it some-mssql /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P VeryStrongPassword@2019 -d DockerTest -Q "select count(*) from [DockerTest].[dbo].[DockerTestTable]"

Gelukkig heb ik een backup gemaakt en kan deze worden teruggezet.

$ docker exec -it some-mssql /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P VeryStrongPassword@2019 -d DockerTest -Q "USE [master] ; ALTER DATABASE [DockerTest] SET SINGLE_USER WITH ROLLBACK IMMEDIATE ; BACKUP LOG [DockerTest] TO DISK = N'/var/opt/mssql/data/DockerTest_LogBackup_2019-11-01_09-49-23.bak' WITH NOFORMAT, NOINIT, NAME = N'DockerTest_LogBackup_2019-11-01_09-49-23', NOSKIP, NOREWIND, NOUNLOAD, NORECOVERY , STATS = 5 ;RESTORE DATABASE [DockerTest] FROM DISK = N'/var/opt/mssql/sql_backup/DockerTest_Full.bak' WITH FILE = 1, MOVE N'DockerTest' TO N'/var/opt/mssql/data/DockerTest.mdf', MOVE N'DockerTest_log' TO N'/var/opt/mssql/data/DockerTest_log.ldf', NOUNLOAD, REPLACE, STATS = 5 ;ALTER DATABASE [DockerTest] SET MULTI_USER ; "

Als ik nu kijk naar de records in de tabel, zijn dat weer de originele 10000 records:

$ docker exec -it some-mssql /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P VeryStrongPassword@2019 -d DockerTest -Q "select count(*) from [DockerTest].[dbo].[DockerTestTable]"

"offsite back-up"

Normaal gesproken zou je ervoor zorgen dat een back-upbestand ook beschikbaar is buiten je server. Met het scheiden van de container en het storage volume hebben we dit eigenlijk al voor elkaar gekregen. Toch ga ik je laten zien hoe je de back-upbestanden uit de container of het storage volume kan halen. Ook ga ik laten zien hoe je de back-upbestanden in een gedeelde map kan zetten zodat ze beschikbaar zijn op de host en in de container.

Back-upbestanden ophalen uit de container

Om files op te halen uit de container zodat ze beschikbaar worden op de host, is er binnen Docker het cp commando. Hiermee kunnen files worden uitgewisseld tussen de host en de container. Laten we beginnen met het ophalen van de eerder gemaakte back-up naar de lokale host.

Ik heb een directory aangemaakt op mijn host computer c:\SQL_BACKUP waar het back-upbestand kan komen te staan. Met onderstaand commando wordt de eerder gemaakte file overgehaald naar mijn lokale host:

$ docker cp some-mssql:/var/opt/mssql/sql_backup/DockerTest_Full.bak "c:\SQL_BACKUP"

Dit commando is als volgt opgebouwd:

cp: het docker commando

some-mssql:/var/opt/mssql/sql_backup/DockerTest_Full.bak: container + : + path + file

”C:\SQL_BACKUP”: lokale path

Omdat ik Windows gebruik en omdat Docker : als scheidingsteken gebruikt, heb ik mijn lokale path tussen aanhalingstekens gezet.

Als ik dit commando uitvoer, zal de file DockerTest_Full.bak op locatie /var/opt/mssql/sql_backup in container some-mssql worden opgehaald en geplaatst in C:\SQL_BACKUP

Files uploaden naar de container

Andersom is natuurlijk ook zeer gewenst: dat je je back-up in de container beschikbaar kan maken, als deze lokaal staat. Ook hiervoor kan het cp commando gebruikt worden, maar dan andersom:

$ docker cp "c:\SQL_BACKUP\DockerTest_Full.bak" some-mssql:/var/opt/mssql/sql_backup/

Het commando is in de basis hetzelfde als het vorige commando en bestaat uit een originele file ("c:\SQL_BACKUP\DockerTest_Full.bak") en een locatie (/var/opt/mssql/sql_backup) op de container (some-mssql) waar de file geplaatst moet worden.

Meer weten?

Dit is een van de vele dingen die Docker te bieden heeft. Ben je enthousiast geworden en wil je meer weten? Heb je hulp nodig bij het ontwerpen met en implementeren van Docker en of SQL Server? Neem gerust eens vrijblijvend contact op! We denken graag met je mee.

Blog deel 1 SQL Server draaien op Docker

Terug naar blog overzicht

 

React