MacOS uzerinde Docker ile MsSQL DB Recovery

05.02.2024

MacOS içerisinde Docker ile MsSQL Server Kullanmak ve Veri Tabanı Kurtarmak

Description

Merhabalar, bu yazımda sizlere macOS içerisinde Docker ile nasıl MsSQL server ayağa kaldırabileceğinizi ve içerisinde nasıl örnek bir veri tabanı kurtarması gerçekleştirebileceğinizi anlatacağım.

Gerekli araçlar:

1- Intel işlemcili Macbook (Apple Silicon işlemcileri için Microsoft desteği sonlanmış vaziyette fakat Docker Desktop ayarlarından Use Rosetta for x86/amd64 seçeneği aktif hale getirilerek bu yazı takip edilebilir. )

2 — Docker

3 — Veri Tabanı Yedek Dosyası

1. Dockerfile ile Konteyner oluşturma

Öncelikle bilgisayarınızda Docker yok ise resmi sitesinden indirebilirsiniz. Çalışma için yeni bir klasör ve içerisinde ‘Dockerfile’ adında yeni bir dosya oluşturalım. Ve dosyanın içerisine şu komutları ekleyelim:

FROM mcr.microsoft.com/mssql/server:2022-latest
ENV ACCEPT_EULA=Y
ENV MSSQL_TCP_PORT=1433

Satır 1 -> Kendi imajımızı üzerine inşa edeceğimiz DocherHub’daki Microsoft SQL Server Ubuntu imajı

Satır 2 -> Kullanım koşullarını kabul eden env variable

Satır 3 -> Bu imajdan oluşturacağımız konteynerin iletişim sağlayacağı portu belirleyen env variable

Bu Dockerfile’i build ettiğimizde DockerHub üzerindeki Microsoft imajını bilgisayarımıza indirecek (halihazırda yoksa) ve bu imajı sararak isteğimize hizmet edecek bir konteyner oluşturmamıza imkan sağlayacak.

İmaj dosyamızı oluşturduktan sonra bulunduğumuz klasör içerisinde bir terminal açıp şu kodu çalıştırıyoruz:

docker build . -t mymssql:latest

Bu kod bizim Dockerfile isimli dosyamızdan imajımızı oluşturacak ve biz de bundan konteyner oluşturacağız.

2. Docker İmajından Konteyner Oluşturma

Oluşturduğumuz imajları ‘docker images’ komutu ile listeleyelim:

Bu komuttan sonra muhtemelen yukarıdakine benzer bir sonuç göreceksiniz. Bunlar sistemimizde bulunan imajlardır. Şimdi mymssql isimli latest taglı imajımdan bir konteyner oluşturacağım:

Bunun için şu komutu çalıştırmamız gerekiyor:

docker run -e "MSSQL_SA_PASSWORD=GucluSifrem1-" -p 1433:1433 -v /Users/shared/msSQLdb/data:/var/opt/mssql/data -v /Users/shared/msSQLdb/log:/var/opt/mssql/log -v /Users/shared/msSQLdb/secrets:/var/opt/mssql/secrets - name mymssqlkonteyner -d mymssql:latest

Bu komut az önce oluşturuğumuz mymssql:latest imajından mymssqlkonteyner isminde admin şifresi GucluSifrem1- olan ve sistemimle 1433 portundan haberleşen bir konteyner çalıştıracak. -v ile sistemim ve konteyner için birden çok volume tanımladım. Bunun nedenini daha sonra açıklayacağım.

Oluşturduğumuz konteyneri görmek için docker ps komutunu çalıştıralım. Mymssqlkonteyner isminde bir konteyner görmeliyiz. Bu konteyner id’si bize gerekli dolayısıyla kopyalayalım. Şimdi bu konteyner terminaline bağlanalım ve içerisindeki veri tabanlarını listeleyelim. (Bunun yerine Docker Desktop arayüzünden çalıştırdığımız konteynerı bulup terminaline de erişebiliriz. )

docker exec -it KONTEYNER_ID bash

Bu komut bizi konteyner içerisindeki terminale eriştirdi. Şimdi bu terminaldeyken aşağıdaki komutla bu konteyner içerisindeki veri tabanlarını görelim. (Veya bunun yerine DBeaver benzeri uygulamalar kullanarak arayüzden bağlanıp görebiliriz)

/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P 'GucluSifrem1-' -Q "sp_databases"

Bu komut sqlcmd aracı ile konteyner içerisindeki tüm veri tabanlarını listeyelecektir. ( Sqlcmd aracı standard olarak 2017 sonrası imajlarda yüklü geliyor, fakat bundan eski bir sürüm kullanıyorsanız ekstra olarak bu aracı yüklemeniz gerekli. )Standart olarak gelen veri tabanları dışında herhangi bir şey görmüyor olmamız lazım.

‘master model msdb tempdb’ standard olarak MsSQL imajıyla beraber gelen veri tabanlarıdır.

3. Konteyner’e Bağladığımız Volume’ler ile Backup İşlemi

Şimdi konteyneri çalıştırırken bağladığımız volume’leri kullanma zamanı. Konteyneri oluştururken kendi bilgisayarımızda /Users/shared/msSQLdb klasörü altınaki data log ve secrets klasörlerini konteyner içerisindeki /var/opt/mssql klasörü altındaki data log ve secrets klasörlerine bağladık. Bu şu demek, konteyner ne zaman kendi sistemi içerisindeki /var/opt/mssql içerisindeki data log ve secrets klasörlerine erişmek istese aslında bizim bilgisayarımızdaki /Users/shared/msSQLdb klasörü altındaki data log ve secrets klasörlerine erişecek. Ve biz bu klasörler altında kendi sistemimizde bir değişiklik yaparsak, konteyner bu değişiklikleri kendi sisteminde görecek. Yani ortak paylaşımlı depolama alanı olarak kullanıyoruz. Şimdi kurtarmak istediğimiz veri tabanı yedek dosyasını bilgisayarımızdaki /Users/shared/msSQLdb/data klasörü içerisindeki backups klasörüne atalım. Bu klasörü önce oluşturalım. Ben https://learn.microsoft.com/en-us/sql/samples/adventureworks-install-configure?view=sql-server-ver16&tabs=ssms içerisinde yer alan AdventureWorks2022 yedeğini kullanacağım. İşlemler hızlı olsun diye de hafif versiyonunu indirdim. Siz farklı bir dosya kullanabilirsiniz. Şimdi veri tabanı yedek dosyasını kurtarmak için 2 aşamalı bir işlem yapacağız. Önce yedek dosyasını keşfedeceğiz sonrasında kurtarma işlemini gerçekleştireceğiz. Yedek dosyasını keşfetmek için flonly.sql isimli bir dosya oluşturalım ve içerisine şu komutları ekleyelim:

USE [master];
GO
RESTORE FILELISTONLY FROM DISK = '/var/opt/mssql/data/backups/AdventureWorksLT2022.bak'
GO

Bu SQL dosyasını da bilgisayarımızdaki backups klasörüne atalım. Bu dosyayı sqlcmd ile terminal konsolundan çalıştırdığımızda bize AdventureWorksLT2022.bak içerisindeki yedek dosyasının özetini verecek. Dikkat ederseniz dosyayı kendi sistemimdeki /Users/shared/msSQLdb/data/backups içerisine atmış olmama rağmen işlemleri konteynerda gerçekleştireceğim için /var/opt/mssql/data/backups klasörünü hedef olarak gösterdim. Şimdi dosya içerisinde ne olduğunu görmek için konteyner terminalinde şu komutu çalıştıralım:

/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P 'GucluSifrem1-' -i /var/opt/mssql/data/backups/flonly.sql

Bu komut çalıştığında bize AdventureWorksLT2022.bak içerisinde yer alan AdventureWorksLT2022_Data ve AdventureWorksLT2022_Log hücrelerini gösterecek. Sizin yedek dosyasına göre bu isimler değişebilir ama genel olarak data ve log dosyaları bulunur. Ek satırları da kaydetmelisiniz. Bu bilgiler ışığında restore.sql isimli dosyamızı oluşturalım. restore.sql dosyasına şu komutları ekleyip kendi bilgisayarımızdaki backup klasörüne taşıyalım:

USE [master];
GO
RESTORE DATABASE [AdventureWorksLT2022]
FROM DISK = '/var/opt/mssql/data/backups/AdventureWorksLT2022.bak'
WITH
MOVE 'AdventureWorksLT2022_Data' TO '/var/opt/mssql/data/AdventureWorksLT2022.mdf',
MOVE 'AdventureWorksLT2022_Log' TO '/var/opt/mssql/log/AdventureWorksLT2022_log.ldf',
REPLACE,
NOUNLOAD,
STATS = 5;
GO

Bu dosyada yer alan MOVE komutları çok önemli, bunun karşısında yer alan dosya isimlerini az önceki keşif işlemimize göre belirlememiz gerekiyor. Az önce elde ettiğimiz ‘AdventureWorksLT2022_Data’ hücresini /var/opt/mssql/data/AdventureWorksLT2022.mdf’ye taşıyoruz ve log dosyası için de aynısını yapıyoruz. Siz kendi dosyalarınıza göre buraları yeniden isimlendirmelisiniz ve ek dosyanız varsa onu da eklemelisiniz. Bu sql dosyasını yine şu komutla sqlcmd ile çalıştıralım:

/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P 'GucluSifrem1-' -i /var/opt/mssql/data/backups/restore.sql

Bu komutu çalıştırdan sonra başarıyla veri tabanı kurtarma işlemimiz tamamlanmış olmalı, fakat bazı kullanıcılarda yetki probleminden dolayı hatalar gözükebiliyor. Eğer bu aşamada

‘File ‘AdventureWorksLT2022_Data’ cannot be restored to ‘/var/opt/mssql/data/AdventureWorksLT2022.mdf’. Use WITH MOVE to identify a valid location for the file.’

benzeri bir hata alıyorsanız, yetkilendirme probleminden dolayı bunu alıyor olabilirsiniz. Bunun kısa bir çözümü mevcut: hatayı aldığınız dosyalar için teker teker terminalden o dosyayı

touch

komutu ile oluşturmak. Örnek:

/var/opt/mssql/data/AdventureWorksLT2022.mdf için hata aldım o yüzden konteyner terminali içinden

touch /var/opt/mssql/data/AdventureWorksLT2022.mdf

yapıp bu dosyayı oluşturuyorum. Ve komutu tekrar çalıştırıyorum.

Bu işlem sonunda buna benzer bir süreç sonunda başarı mesajı görmeliyiz. Hemen kontrol edelim veri tabanını başarıyla kurtarmış mıyız:

Görüldüğü gibi veri tabanını başarıyla kurtarmışız. Şimdi konteynerimizi durduralım ve yeni bir konteyner oluşturalım aynı volume’ler ile. Böylelikle kurtarmış olduğumuz veri tabanımızın yerinde durduğunu görelim.

docker stop KONTEYNER_ID

ile konteynerimi durduruyorum.

Yeni bir konteyner oluşturuyorum aynı volume’ler ile :

docker run -p 1433:1433 -v /Users/shared/msSQLdb/data:/var/opt/mssql/data -v /Users/shared/msSQLdb/log:/var/opt/mssql/log -v /Users/shared/msSQLdb/secrets:/var/opt/mssql/secrets - name baskakonteyner -d mymssql:latest

Konteyner terminalime bağlanıyorum ve veri tabanlarını gösteriyorum:

alt

Dikkat ettiyseniz şifrem ilk konteyner ile aynı çünkü SA kullanıcısı için şifremi de volume içerisine bağlamıştım. İhtiyari olarak değiştirmezseniz değişmeyecektir. Onu da isterseniz sonra konteyner terminaline bağlandıktan sonra şu şekilde değiştirebilirsiniz:

opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P 'GucluSifrem1-' -Q "ALTER LOGIN sa WITH PASSWORD = 'GucluSifrem2-' UNLOCK"

Sonuç :

Bu yazımızda öncelikle resmi Microsoft SQL Server Ubuntu imajını kullanan Dockerfile dosyamızla kendi imajımızı oluşturduk, bu imajla konteyner çalıştırdık ve volume’ler bağladık. Bağladığımız volume’leri kullanarak sistemler arası dosya ilettik. Daha sonra veri tabanı yedek dosyasını keşfedip dosya içeriğine göre veri tabanı kurtarma komut dosyası oluşturup bu dosya ile kurtarma gerçekleştirdik. Ve konteynerları silsek, yeniden oluştursak dahi yedeklerimizin kaybolmadığını gördük. Yedekten kurtarma işlemi gerçekleştirirken alabileceğimiz hatalara çözümler sunduk. Ve en sonunda istersek veri tabanı yönetici kullanıcısının şifresini değiştirmeyi gördük. Yazımızın sonuna geldik. Okuduğunuz için teşekkürler.

Proje GitHub Link : https://github.com/ibrahimhalici/macOS-msSQLServer

Kaynaklar :

https://learn.microsoft.com/en-us/sql/samples/adventureworks-install-configure?view=sql-server-ver16&tabs=ssms

https://hub.docker.com/_/microsoft-mssql-server

https://www.cocosenor.com/articles/office/how-to-change-sql-sa-password-from-a-command-prompt.html

https://learn.microsoft.com/en-us/sql/linux/quickstart-install-connect-docker?view=sql-server-ver16&pivots=cs1-bash

This article converted from a Medium Post by this tool.