Målet
At holde to databaser synkroniseret er en opgave, vi ofte støder på, når vi arbejder med udvikling og vedligeholdelse af SQL-databaser. Et særligt tilfælde er dette - versionerne af en database, der findes på test- og udviklingsmiljøer, skal synkroniseres konsekvent for at sikre, at test kører på den seneste version. Dette bør gøres ved at detektere skemaændringer i udviklingsversionen af en database og derefter automatisk synkronisere dem med versionen fra testmiljøet på en planlagt basis.
Sådan opnår du det
Vi vil se nærmere på, hvordan automatiseret synkronisering af to SQL-databaser kan opnås ved at kombinere et skemasammenligningsværktøj med PowerShell-scripts og planlægning.
I eksemplet, vi skal se, vil databaserne blive synkroniseret hvert 15. minut. Da vi bruger et skemasammenligningsværktøj, kan vi være sikre på, at databasen kun bliver opdateret, hvis der er nogle faktiske ændringer mellem udviklings- og testversionerne af databasen – dette forhindrer udførelse af unødvendige ressourcetunge operationer.
Vi bruger Devart Schema Compare som det foretrukne værktøj til at differentiere og synkronisere SQL Server-databaser. Det er et værktøj, der giver dig mulighed for at sammenligne og synkronisere live SQL Server-databaser, snapshots og sikkerhedskopier. Lad os se på, hvordan vi kan implementere vores projekt nedenfor.
Opsætning
Først og fremmest skal vi konfigurere nogle ting:
- Kør Schema Compare
- Klik på ‘Ny skemasammenligning ' knappen på værktøjslinjen eller alternativt øverst til højre på startsiden:
- I Kilde og mål fanebladet Ny skemasammenligning vindue, vælg den ønskede kilde og måldatabaser:
- I Indstillinger , Skemakortlægning og Tabelkortlægning faner, kan du opsætte de nødvendige sammenlignings- og synkroniseringsmuligheder:
- Når alt er sat op, kan du trykke på ‘Sammenlign ' knappen i nederste højre hjørne for at starte sammenligningsprocessen.
- Når sammenligningen er færdig, kan du se alle objekter, der er blevet sammenlignet, og deres respektive forskelsstatus i den øverste del af vinduet, mens det detaljerede script for hvert af disse objekter vil være placeret nederst:
- Tjek alle objekter for at inkludere dem i synkroniseringsprocessen, og klik på ‘Gem ' eller tryk på Filer> Gem :Dette vil gemme projektet med alle de oplysninger, vi har brug for for at starte synkroniseringsprocessen.
- Når projektet er gemt, skal du klikke på 'Synkroniser objekter ’ knap:
- Schema Synchronization Wizard vil blive åbnet. Først skal du vælge "Udfør scriptet direkte mod måldatabasen ' i Output fane:
- Du kan vælge de nødvendige indstillinger i Indstillinger fane:
- Du kan kontrollere alle objekter, der skal synkroniseres i Oversigt fane:
- Klik på ‘Synkroniser ' i nederste højre hjørne for at teste synkroniseringsprocessen.
- Du vil se resultaterne vist i den nederste rude af vinduet:
Automatisering af processen
Da skemasynkronisering var vellykket, og nu hvor vi har en projektfil med al den nødvendige information, lad os automatisere synkroniseringsprocessen ved at bruge et PowerShell-script.
I det følgende eksempel antages det, at du bruger integreret sikkerhed, men den lagrede og krypterede database kan stadig nemt tilgås fra projektfilen sammen med arkivets legitimationsoplysninger.
Vi vil se på nogle dele af scriptoprettelsesprocessen, som kan være særligt interessante, men du er velkommen til at springe dette afsnit over for at downloade og teste det færdige script med det samme.
Oprettelse af et script
Først skal vi oprette en funktion, der kontrollerer, om mappen Outputs eksisterer. Denne mappes formål er at gemme datastemplede forpligtelsesoversigter. Funktionen skal se sådan ud:
#check if the Outputs folder exists function CheckAndCreateFolder($rootFolder, [switch]$Outputs) { $location = $rootFolder #setting up its location if($Outputs -eq $true) { $location += "\Outputs" } #creating the folder if it doesn't currently exist if(-not (Test-Path $location)) { mkdir $location -Force:$true -Confirm:$false | Out-Null } return $location }
Dernæst definerer vi rodmappen og placeringen af skemaoutputresuméer:
#defining the root folder for the synchronization process $rootFolder = "d:\temp\SchemaSync" #defining the location of schema output summaries $outsLoc = CheckAndCreateFolder $rootFolder -Outputs
Nu bliver vi nødt til at definere Schema Compares placering, datostempelvariablen og applikationens parametre:
#Schema Compare location and the date stamp variable are defined, as well as the tool’s parameters $diffLoc = "C:\Program Files\Devart\dbForge Studio for SQL Server\dbforgesql.com" $stamp = (Get-Date -Format "Mmddyyyy_HHMMss")
Med dette på plads kan vi indstille stien til outputlogfilen:
#output log file path $logPath = "$outsLoc\SchemaOutput_$stamp.txt" $Params = "/schemacompare /compfile:""D:\temp\SchemaSync\Project\AdventureWorksLTDvsAdventureWorksDW.scomp"" /log:""$logPath""" $sync = " /sync"
Dernæst kalder vi Schema Compare og lader det udføre sine synkroniseringsparametre:
#initiate the schema comparison and synchronization process (Invoke-Expression ("& `"" + $diffLoc +"`" " +$Params)) $returnCode = $LASTEXITCODE $message = ""
Den sidste del af scriptet vil tjene til at definere alle mulige resultater:
- Skemaændringer er registreret, returner kode 0 – Succes
- Ingen skemaændringer fundet, returkode 100– Ingen skemaændringer fundet
- Der er opstået en fejl, og outputoversigten vil blive åbnet.
if ($returnCode -notin (100, 101)) { #an error is encountered $logPath = "$outsLoc\SchemaOutput_error.txt" $message >> $logPath clear-content $logPath $message = "`r`n $returnCode - An error is encountered" #output file is opened when an error is encountered Invoke-Item "$logPath" } else{ if ($returnCode -eq 101) { clear-content $logPath (Invoke-Expression ("& `"" + $diffLoc +"`" " +$Params+$sync)) $returnCode = $LASTEXITCODE #schema changes are detected } if($returnCode -eq 0) { $message = "`r`n $returnCode - Schema changes were successfully synchronized" } else { #there are no schema changes if($returnCode -eq 100) { $message = "`r`n $returnCode - There are no schema changes. Job aborted" } } } $message >> $logPath
Planlægning
Med PowerShell scriptet klar og processen automatiseret, kan vi planlægge dette på et par forskellige måder, f.eks. via Windows Scheduler.
Viser resultater
Nu hvor det planlagte job er oppe at køre, kan du se skemaoutputoversigter, når som helst du har brug for det. I eksemplet, vi lige så, definerede $outsLoc-variablen placeringen af skemaoutputresuméer. Som et resultat vil sådanne oversigter blive gemt i $rootFolder\$outsLoc – i dette særlige tilfælde, SchemaSync\Outputs:
Hvis der opstår en fejl, f.eks. en projektfils udvidelse er indtastet forkert, vil den tilsvarende fejlmeddelelse blive vist i outputoversigten.
Listen over returfejlkoder hjælper os til bedre at forstå den specifikke fejl, vi stødte på.
[expand title =”FULD SCRIPT “]
#check if the Outputs folder exists function CheckAndCreateFolder($rootFolder, [switch]$Outputs) { $location = $rootFolder #setting up its location if($Outputs -eq $true) { $location += "\Outputs" } #creating the folder if it doesn't currently exist if(-not (Test-Path $location)) { mkdir $location -Force:$true -Confirm:$false | Out-Null } return $location } #defining the root folder for the synchronization process $rootFolder = "d:\temp\SchemaSync" #defining the location of schema output summaries $outsLoc = CheckAndCreateFolder $rootFolder -Outputs #Schema Compare location and the date stamp variable are defined, as well as the tool’s parameters $diffLoc = "C:\Program Files\Devart\dbForge Studio for SQL Server\dbforgesql.com" $stamp = (Get-Date -Format "Mmddyyyy_HHMMss") #output log file path $logPath = "$outsLoc\SchemaOutput_$stamp.txt" $Params = "/schemacompare /compfile:""D:\temp\SchemaSync\Project\AdventureWorksLTDvsAdventureWorksDW.scomp"" /log:""$logPath""" $sync = " /sync" #initiate the schema comparison and synchronization process (Invoke-Expression ("& `"" + $diffLoc +"`" " +$Params)) $returnCode = $LASTEXITCODE $message = "" if ($returnCode -notin (100, 101)) { #an error is encountered $logPath = "$outsLoc\SchemaOutput_error.txt" $message >> $logPath clear-content $logPath $message = "`r`n $returnCode - An error is encountered" #output file is opened when an error is encountered Invoke-Item "$logPath" } else{ if ($returnCode -eq 101) { clear-content $logPath (Invoke-Expression ("& `"" + $diffLoc +"`" " +$Params+$sync)) $returnCode = $LASTEXITCODE #schema changes are detected } if($returnCode -eq 0) { $message = "`r`n $returnCode - Schema changes were successfully synchronized" } else { #there are no schema changes if($returnCode -eq 100) { $message = "`r`n $returnCode - There are no schema changes. Job aborted" } } } $message >> $logPath
[/udvid]
Hvis der opstår spørgsmål eller problemer under processen med at konfigurere dette, er du velkommen til at kontakte os når som helst på [email protected]